我在.h文件中声明了一个属性为
@property (weak, nonatomic) UIPickerView *levelPicker;
在我的实现文件中合成为:
@synthesize levelPicker = _levelPicker;
然后我在同一个实现文件中有一个代码块,它执行以下操作:
if (self.levelPicker == nil) {
self.levelPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
self.levelPicker.delegate = self;
self.levelPicker.dataSource = self;
}
textField.inputView = self.levelPicker;
在这种情况下,self._levelPicker未设置为新的UIPickerView。即self.levelPicker = blah赋值不起作用。
但是,如果我将属性声明更改为:
@property (strong, nonatomic) UIPickerView *levelPicker;
然后一切按预期工作,_levelPicker设置为新分配的UIPickerView。
有人可以告诉我为什么会这样吗?我以为我正在理解参考是如何工作的,但我想我还有更多要学习的东西。我读了一些其他相关的SO帖子,但对我来说仍然不完全清楚。
答案 0 :(得分:7)
正如@Inazfiger所说,你的对象需要至少一个强(保留)引用,否则它们将不被保留。
在这种情况下,您将选择器视图分配给UITextField
的{{1}}属性。文本字段将保留选择器视图(我知道这是因为inputView
上的inputView
属性为declared with the modifiers "readwrite, retain"),但只有在您完成作业后才 。因此,如果您想坚持使用弱引用,则需要稍微重新排列代码 - 如下所示:
UITextField
答案 1 :(得分:4)
嗯,简短的回答是作业确实有效。
但是,由于它是一个弱引用,因此没有保留,因为没有(其他)强引用您的选择器并且它自动设置为nil。
必须至少有一个强引用任何对象,否则它不会被保留,在这种情况下没有。
有关详细信息,请参阅Apple的“过渡到ARC发行说明”中的“ARC Introduces New Lifetime Qualifiers”。
Ray Wenderlich为此here创建了一个很棒的教程。
答案 2 :(得分:1)
强大的"限定符创建一个所有者关系,用于停止释放被解除对象的对象,这与之前在非ARC世界中所做的相同:
@property(retain) NSObject *obj;
虽然"弱"限定符不会创建所有者关系,因此将像以前一样取消分配对象:
@property(assign) NSObject *obj;
在您的情况下,您需要第一个关系,因为您需要实例变量(_levelPicker)来保持新创建的UIPickerView实例。你做的弱任务实际上有效,但很快就被解除了分配。