iOS 7中引用计数的更改?

时间:2013-09-26 10:46:10

标签: ios objective-c xcode ios7 reference-counting

我正在努力修复一些未使用ARC构建的旧应用程序上的iOS 7显示问题,并且在iOS版本6和版本之间使用dealloc方法遇到了一些不一致的行为。 7.我在任何文件或社区讨论中都找不到任何其他提及这些变化的内容,所以我想知道这里是否有人可以了解这里发生的事情?

我之前的代码(在iOS6中有效,如下所示):

@interface MyViewController()
@property (retain) AdHandler *adHandler;
@end

@implementation MyViewController

@synthesize adHandler = _adHandler;

- (id) initWithAdHandler:(AdHandler*)anAdHandler
{
    self = [super init];
    _adHandler = [anAdHandler retain];
    return self;
}

- (void)dealloc
{    
    [super dealloc];

    [_adHandler release];
    _adHandler = nil;
}

...

@end

在iOS 6中逐步执行代码时,我发现在dealloc语句后,[_adHandler retainCount]仍然是正数,并且该对象仍然可用。

但是,在iOS 7中,在dealloc语句之后,retainCount以某种方式命中为零,_adHandler对象已经dealloc',因此我的号召是release会导致EXC_BAD_ACCESS

我可以通过将[adHandler release]来电转移到dealloc来电之前解决此问题,但我的问题是为什么会发生这种情况?为什么dealloc发布它不负责的对象?是否存在任何关于为什么dealloc行为以这种方式发生了变化的文档?

2 个答案:

答案 0 :(得分:6)

[super dealloc]之后,实例是垃圾,无论发生什么都是随机且非确定性的。正如@bneely所写,[super dealloc]必须是最后的。

最佳做法:转换为ARC。

对于retainCount,不保证它的价值可能是什么,不要使用它,它只会造成混乱。在您的情况下,您通过调用[super dealloc]来销毁类实例,然后期望实例表现得好像它仍然存在。它不能,它已被破坏,现在只是内存中的一些非确定性位。

答案 1 :(得分:0)

You should never use retain count.

您返回的值无法以任何合理的方式解释。因此,完全期望在不同的iOS版本,设备上看到不同的结果,具有不同的代码位等等。


另一方面,您考虑转换到ARC吗?代码将大大简化。另请注意,如果您要实现UIViewController的子类,则不应使用init对其进行初始化。而只是声明属性,ARC将负责其setter和getter:

@interface MyViewController : UIViewController
@property AdHandler *adHandler;
@end

// somewhere else 
MyViewController * mvc = ... from nib or in some other way ...
mvc.adHandler = myAdHandler;

现在你可以保证没有糟糕的访问。