微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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().

原文地址:https://www.jb51.cc/c/113025.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐