以下是我验证问题的代码。
我创建了两个类,A& B:
@interface A : NSObject
@property (strong, nonatomic) B *b;
@end
@implementation A
- (void)dealloc
{
[_b release];
[super dealloc];
}
@end
//
@interface B : NSObject
@property (nonatomic, strong) A *a;
@end
@implementation B
- (void)dealloc
{
[_a release];
[super dealloc];
}
@end
//在StrongViewController
中,有tempA和tempB,它们都是proprety:
@interface StrongViewController ()
@property (nonatomic, assign) A *tempA;
@property (nonatomic, assign) B *tempB;
@end
//在viewDidLoad
中,我创建了一个保留周期,一个& b互相保留:
A *a = [[[A alloc] init] autorelease];
B *b = [[[B alloc] init] autorelease];
a.b = b;
b.a = a;
self.tempA = a;
self.tempB = b;
//然后在viewWillDisappear
中,我尝试打破保留周期:
[super viewWillDisappear:animated];
self.tempA.b = nil; // Key line
//现在,逐步进入循环。
我在A的dealloc&中设置了两个断点。 B的dealloc:
//现在执行了关键行self.tempA.b = nil;
:
// B已dealloc
被调用,因为release
消息已发送到A setB
中的b:
//在B的dealloc
中,release
消息被发送到a,因此A的dealloc
被调用:
//现在,_b是nil
因为我们使用默认的setB:
,所以可以通过。
//但是如果使用如下所示的自定义setB:
会怎么样:
//执行关键线self.tempA.b = nil;
后,它会遇到自定义setB:
:
//现在release
被发送到b,所以它转到了B的dealloc
:
//请注意,在B的dealloc
中,[self retainCount]仍为1,而不是0,为什么?
//在B的dealloc
中,release
被发送到_a,因此它将依次转到A的dealloc
,并在那里release
将被发送到_b:
//差异很大,在A的dealloc中,_b
不是nil,_b的retainCount
是1。
//据我所知,如果_b现在收到release
消息,那么它会调用dealloc
,因为它的retainCount目前为1。
//但是,出于我的想象,它不会递归地进入B的dealloc
,而只是跳到下一行,让retainCount
具有较大的值{{1} }:
//我的问题是上述问题,为什么当_b收到2147483648
消息时,它会跳过,而不是踩到release
,而dealloc
仍然 1 ?
// retainCount retainCount
是如何出来的?
//深入了解NSObject在收到“发布”消息时的工作原理,任何人都知道源代码?即使在A 2147483648
中, a 的retainCount`仍为1, b 也是如此。
答案 0 :(得分:3)
当您释放保留计数为1的对象时,会发生以下情况:
该对象标记为“死”。
调用dealloc方法。
对象的内存返回给操作系统。
当对象标记为死时,保留和释放无效。在调用dealloc之前,运行时甚至不打算将retain count设置为零。当您的第二个dealloc方法被调用并尝试释放已经死亡的对象时,即使retainCount返回1,也没有任何反应。对于同一个对象,dealloc永远不会被调用两次。
答案 1 :(得分:1)
http://www.opensource.apple.com/source/objc4/objc4-532/runtime/NSObject.mm值得一试。
我认为问题与hasCustomRR()有关,但我发现代码很难跟随,所以可能是错误的。
答案 2 :(得分:-1)
不要在对象之间保持循环引用! 但是需要一些时间来使用这些引用来完成我们的任务。 所以我建议如果你有一个对象依赖于其他,那么你可以使用参考WEAK.It将确保打破引用的循环循环。您可以参考http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html教程获取更多解释。