objective-c – 在dealloc中,弱的属性设置为nil,但属性的ivar不为零

我注意到在启用ARC的Objective-C中有以下内容

我们有简单的A级和自动合成弱的属性

@interface A
@property (nonatomic,weak) id refObject;
@end

@implementation A
@end

和第二类B与dealloc实现

@interface B
@end

@implementation B
-(void) dealloc
{
    NSLog(@"In dealloc");
}
@end

最后在A班的某个地方有以下几个:

@implementation A
...
-(void) foo
{
   B* b = [B new];
   self.refObject = b;
   // Just use b after the weak assignment
   // in order to not dealloc 'b' before assignement 
   NSLog(@"%@",b);
}
...
@end

如果我在[B dealloc]中设置一个断点并检查[A refObject]属性,我可以看到a.refObject为零,但a-> _refObject不为零,指向’b’

任何想法为什么会发生?

解决方法

简短的答案:实例变量a-> _refObject不(N)in – [B dealloc]
但是通过ARC运行时功能可以对每个弱指针进行访问
如果释放已经开始,则返回零.

长回答:通过设置一个观察点,您可以看到a-> _refObject在末尾设置为nil
释放过程.堆栈回溯(当观察点被击中时)看起来像这样:

frame #0: 0x00007fff8ab9f0f8 libobjc.A.dylib`arr_clear_deallocating + 83
frame #1: 0x00007fff8ab889ee libobjc.A.dylib`objc_clear_deallocating + 151
frame #2: 0x00007fff8ab88940 libobjc.A.dylib`objc_destructInstance + 121
frame #3: 0x00007fff8ab88fa0 libobjc.A.dylib`object_dispose + 22
frame #4: 0x0000000100000b27 weakdealloc`-[B dealloc](self=0x000000010010a640,_cmd=0x00007fff887f807b) + 151 at main.m:28
frame #5: 0x0000000100000bbc weakdealloc`-[A foo](self=0x0000000100108290,_cmd=0x0000000100000e6f) + 140 at main.m:41
frame #6: 0x0000000100000cf5 weakdealloc`main(argc=1,argv=0x00007fff5fbff968) + 117 at main.m:52
frame #7: 0x00007fff8c0987e1 libdyld.dylib`start + 1

和object_dispose()从 – [NSObject dealloc]调用(可以在
http://www.opensource.apple.com/source/objc4/objc4-532/runtime/NSObject.mm).

因此在 – [B dealloc]中,a-> _refObject在调用(编译器生成)[super dealloc]之前不为零.

所以问题仍然存在:为什么a.refObject在这个时候返回nil?

原因是每次访问ARC编译器生成的弱指针
调用objc_loadWeak()或objc_loadWeakRetained().从documentation

id objc_loadWeakRetained(id *object)

If object is registered as a __weak object,and the last value stored into object has not > yet been deallocated or begun deallocation,retains that value and returns it. Otherwise > returns null.

所以即使在这个时候ref- ref对象不是零,访问弱指针
通过objc_loadWeakRetained()(由属性访问器方法完成)返回nil,
因为B对象的释放已经开始了.

调试器直接访问 – > refObject,不调用objc_loadWeak().

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...