Stu*_*art 4 weak-references objective-c release-builds ios automatic-ref-counting
我有一个懒惰创建对象的类,并将其存储为弱属性.其他类可能会请求此对象,但显然必须对其进行强引用以防止对象被释放:
// .h
@interface ObjectManager
@property(nonatomic, weak, readonly) NSObject *theObject;
@end
// .m
@interface ObjectManager ()
@property(nonatomic, weak, readwrite) NSObject *theObject;
@end
@implementation ObjectManager
- (NSObject *)theObject
{
if (!_theObject) {
_theObject = [[NSObject alloc] init];
// Perform further setup of _theObject...
}
return _theObject;
}
@end
Run Code Online (Sandbox Code Playgroud)
当方案是Xcode被设置为为Debug构建时,一切正常 - 一个对象可以调用objectManagerInstance.theObject并返回theObject.
当方案设置为Release版本时,theObject返回nil:
// Build for Debug:
NSObject *object = objectManagerInstance.theObject;
// object is now pointing to theObject.
// Build for Release:
NSObject *object = objectManagerInstance.theObject;
// object is now `nil`.
Run Code Online (Sandbox Code Playgroud)
我的猜测是编译器通过查看_theObject在访问器方法本身中没有进一步使用来优化我的代码,因此nil在返回之前将弱变量设置为.看来,我必须创建真的返回了变量,我只能认为使用块前做一个有力的参考,但会是麻烦的,我宁愿避免它!
是否有某种关键字我可以使用返回类型来阻止ivar这么快被填满?
最有可能的是,DEBUG构建会导致对象在自动释放池中停留足够长的时间以使其"工作",而RELEASE构建会使优化器进行更多的控制流分析,从而消除自动释放聊天.
坦率地说,编译器没有在发布版本中发出警告说代码永远无法工作是一个错误(请提交它,因为你有一个很棒的,简洁的例子)!
您需要在对象的某处保持强引用,直到需要强引用有机会获取引用.
我想知道这样的事情是否有效:
- (NSObject *)theObject
{
NSObject *strongObject;
if (!_theObject) {
strongObject = [[NSObject alloc] init];
_theObject = strongObject;
// Perform further setup of _theObject...
} else {
strongObject = _theObject;
}
return strongObject;
}
Run Code Online (Sandbox Code Playgroud)
即上面的内容更类似于返回自动释放对象的工厂方法,同时还在内部维护弱引用.但优化器可能太聪明了一半而且也打破了上述情况.
| 归档时间: |
|
| 查看次数: |
659 次 |
| 最近记录: |