我在 View 中添加了两个按属性存储的 subview 。当将 subview 添加到我的 View 时,在调用我的setup
方法之后,该 subview 似乎被释放了。最终结果是 View 永远不会显示。现在,如果我将属性更改为strong
而不是weak
,则保留对 View 的引用,它们现在显示在屏幕上。那么这是怎么回事?为什么addSubview:
和insertSubview:
不保留 subview ?请参见下面的代码:
顺便说一句,我正在将iOS5与ARC配合使用(因此,强项和弱项)
#import "NoteView.h"
@interface NoteView() <UITextViewDelegate>
@property (weak, nonatomic) HorizontalLineView *horizontalLineView; // custom subclass of UIView that all it does is draw horizontal lines
@property (weak, nonatomic) UITextView *textView;
@end
@implementation NoteView
@synthesize horizontalLineView = _horizontalLineView;
@synthesize textView = _textView;
#define LEFT_MARGIN 20
- (void)setup
{
// Create the subviews and set the frames
self.horizontalLineView = [[HorizontalLineView alloc] initWithFrame:self.frame];
CGRect textViewFrame = CGRectMake(LEFT_MARGIN, 0, self.frame.size.width, self.frame.size.height);
self.textView = [[UITextView alloc] initWithFrame:textViewFrame];
// some addition setup stuff that I didn't include in this question...
// Finally, add the subviews to the view
[self addSubview:self.textView];
[self insertSubview:self.horizontalLineView atIndex:0];
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self setup];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
[self setup];
}
return self;
}
最佳答案
这是您的代码行:
self.horizontalLineView = [[HorizontalLineView alloc] initWithFrame:self.frame];
回想一下
horizontalLineView
属性是弱的。让我们通过ARC生成的额外代码逐步了解该行中实际发生的情况。首先,您发送alloc
和initWithFrame:
方法,以获取强大的引用:id temp = [[HorizontalLineView alloc] initWithFrame:self.frame];
此时,
HorizontalLineView
对象的保留计数为1。接下来,因为您使用点语法设置了horizontalLineView
属性,所以编译器生成了将setHorizontalLineView:
方法发送给self
的代码,并通过temp
作为参数。由于HorizontalLineView
属性被声明为weak
,因此setter方法将执行以下操作:objc_storeWeak(&self->_horizontalLineView, temp);
这会将
self->_horizontalLineView
设置为等于temp
,并将&self->_horizontalLineView
放入对象的弱引用列表中。但是,它不会增加HorizontalLineView
对象的保留计数。最后,由于不再需要
temp
变量,因此编译器将生成以下代码:[temp release];
这样可以将
HorizontalLineView
对象的保留计数降低为零,因此可以取消分配该对象。在解除分配期间,它将沿弱引用列表走动,并将每个引用设置为nil
。因此self->_horizontalLineView
变成nil
。解决此问题的方法是使
temp
变量显式,以便您可以延长其生存期,直到将HorizontalLineView
对象添加到其 super View 中为止(保留它):HorizontalLineView *hlv = [[HorizontalLineView alloc] initWithFrame:self.frame];
self.horizontalLineView = hlv;
// ...
[self insertSubview:hlv atIndex:0];
关于iphone - 为什么addSubview : not retaining the view?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9747015/