gpt4 book ai didi

iphone - 为什么addSubview是: not retaining the view?

转载 作者:可可西里 更新时间:2023-11-01 03:24:35 30 4
gpt4 key购买 nike

我正在向我的 View 添加两个按属性存储的 subview 。将 subview 添加到我的 View 时, subview 似乎在我的 setup 方法被调用后被释放。最终结果是 View 永远不会显示。现在,如果我将我的属性更改为 strong 而不是 weak 我会保留对 View 的引用,它们现在会显示在屏幕上。那么这是怎么回事?为什么 addSubview:insertSubview: 不保留 subview ?请看下面的代码:

顺便说一句,我正在使用带有 ARC 的 iOS5(因此有强项和弱项)

#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];

回想一下,horizo​​ntalLineView 属性很弱。让我们通过 ARC 生成的额外代码来了解该行中真正发生的事情。首先,您发送 allocinitWithFrame: 方法,返回一个强引用:

id temp = [[HorizontalLineView alloc] initWithFrame:self.frame];

此时,Horizo​​ntalLineView 对象的保留计数为 1。接下来,因为您使用点语法设置了 horizo​​ntalLineView 属性,所以编译器生成代码以将 setHorizo​​ntalLineView: 方法发送给 self,将 temp 作为参数传递。由于 Horizo​​ntalLineView 属性被声明为 weak,setter 方法执行以下操作:

objc_storeWeak(&self->_horizontalLineView, temp);

设置 self->_horizo​​ntalLineView 等于 temp,并将 &self->_horizo​​ntalLineView 放在对象的弱引用列表中。但它不会增加 Horizo​​ntalLineView 对象的保留计数。

最后,因为不再需要 temp 变量,所以编译器生成了这个:

[temp release];

这会将 Horizo​​ntalLineView 对象的保留计数降低到零,因此它会释放该对象。在释放过程中,它遍历弱引用列表,并将每个弱引用设置为 nil。所以 self->_horizo​​ntalLineView 变成了 nil

解决这个问题的方法是使 temp 变量显式化,这样您就可以延长它的生命周期,直到将 Horizo​​ntalLineView 对象添加到它的父 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/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com