我正在努力修复一些未使用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行为以这种方式发生了变化的文档?
答案 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;
现在你可以保证没有糟糕的访问。