从弱转换为unsafe_unretained导致崩溃?

时间:2012-09-25 17:53:44

标签: objective-c automatic-ref-counting

我有一个专为ARC和iOS 5设计的库,但客户想要为iOS 4.x构建。我将weak qualifer的属性转换为unsafe_unretained,但现在看来我遇到了内存损坏 - esq崩溃。 在崩溃的情况下,我有一个像这样的委托属性

@property (unsafe_unretained) id<MYDelegateProtocol> delegate;

和我@synthesize ivar。

每当我想在委托上调用一个方法时,我会检查它是否为nil,如果不是,那么我调用该方法,因为我在该协议中没有可选方法,我不知道检查respondsToSelector

然而,自从将weak更改为unsafe_unretained后,我发现显然参考文献消失了,而我留下了一个悬空指针。如果我在ObjC Exceptions上设置一个断点,(对于无法识别的消息),然后po对象的地址,我看到它是一个甚至没有实现委托协议的对象,所以当然它崩溃。

使用unsafe_unretained时,我怎么知道引用已“消失”?我的代码依赖指针在之前被清零。

3 个答案:

答案 0 :(得分:2)

您有对象所有权问题。已释放的对象不会为nil,它只是指向对象所在的地址。 nil指针指向0x0。您需要分析在委派的记录存在时,您的体系结构如何具有正在释放的委托。在某些特殊情况下,被委派的对象可能会保留其委托(如NSURLConnection)。在其他情况下,被委派的对象是其委托的属性,在这种情况下,需要在取消分配之前清除委托。分析您的模式和/或提供更多信息。

答案 1 :(得分:2)

试试这个我开发iOSWeakForwarder

的课程

答案 2 :(得分:1)

  

使用unsafe_unretained时,我怎么知道引用有   “走了”?我的代码依赖指针在之前被清零。

这必须由您在编译时确定。通常,作为委托的对象应该将委托给它的对象的delegate属性设置为nil方法中的dealloc。例如:

- (void)dealloc
{
    if (_httpRequest.delegate == self)
        _httpRequest.delegate = nil;
}

希望这有帮助!