更新 2:
在今天早上花了几个小时诊断和记录无法在我的 iOS 5 项目中发布的 ivars 之后,我发现如果在 iOS 5 上打开并运行僵尸,实例变量不会在 ARC 项目中发布。用这些非凡的发现更新我的答案,Calin向我指出,这是众所周知的行为。技术问答 QA1758。谢谢卡林!
我的示例项目位于https://github.com/robertmryan/arc-problem-project
更新:
我之前曾声称这是不正确的,除非您将变量和属性设置为nil
. 我提供了以下代码作为示例。这是从一个真实的 ARC 测试项目中获取的,我什至用另一个视图控制器重新创建了它,除了下面的代码来确认之外,里面什么都没有。经过当之无愧的反对意见后,我将此代码示例放入一个新项目中,并且 ivar 被释放,这是应该的。
因此,它一定与所讨论的项目有关。从那以后,除了下面的代码(以及执行 push segue 的视图控制器,以便我可以弹回它来演示释放)之外,我已经完全从该项目中删除了所有内容,并且问题仍然存在。如果我将代码(和故事板)复制到一个新项目,它工作正常。非常非常奇怪,我会更深入地研究这个。如果您想查看我的项目,请访问https://github.com/robertmryan/arc-problem-project。也许其他人可以看到问题所在。我知道我可以放弃这个项目(它甚至不是一个生产应用程序,只是一个测试平台),但令人担忧的是 ARC 的 dealloc 无法正常工作。
无论如何,要清楚,您的 ivars会随着父对象的释放而释放。我不知道为什么我没有在下面的情况下发布,但这对原始问题无关紧要。
// ArcTestViewController.m
#import "ArcTestViewController.h"
#pragma mark - IvarObject
@interface IvarObject : NSObject
@end
@implementation IvarObject
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
@end
#pragma mark - ArcTestViewController
@interface ArcTestViewController ()
{
IvarObject __strong *_ivarObject;
}
@end
@implementation ArcTestViewController
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
// _ivarObject = nil;
}
- (void)viewDidLoad
{
[super viewDidLoad];
_ivarObject = [[IvarObject alloc] init];
}
@end
当我使用注释掉=nil
的方法中的语句执行此操作时,我在控制台上看到以下内容:dealloc
2012-07-12 10:33:33.644 test4[36045:11903]-[ArcSimpleTestViewController dealloc]
当我在我的 中取消注释该=nil
语句时dealloc
,我看到以下内容:
2012-07-12 10:35:23.117 test4[36083:11903]-[ArcSimpleTestViewController dealloc]
2012-07-12 10:35:23.119 test4[36083:11903]-[IvarObject2 释放]
对于我上面的撤回,当我将相同的代码放在一个新项目中时,无论我是否为 nil,我都会看到 deallocs。
Rob Napier 提供了下面的代码示例(我感谢他和其他人抽出时间),但是当我把上面的代码放在另一个项目中时,即使是上面的代码也能正常工作,但在我当前的项目中,它没有正确释放!
来自 Rob Napier 的更新:演示其工作原理的更简单示例(全部在一个文件中)。将其放入文件中并按照指示进行编译:
// arc.m
// Compile with:
// clang -fobjc-arc -framework Foundation -o arc arc.m
#import <Foundation/Foundation.h>
#pragma mark - IvarObject
@interface IvarObject : NSObject
@end
@implementation IvarObject
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
@end
#pragma mark - PropertyObject
@interface PropertyObject : NSObject
@end
@implementation PropertyObject
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
}
@end
#pragma mark - ArcTest
@interface ArcTest : NSObject
{
IvarObject __strong *_ivarObject;
}
@property (nonatomic, strong) PropertyObject *propertyObject;
@end
@implementation ArcTest
@synthesize propertyObject = _propertyObject;
- (void)dealloc
{
NSLog(@"%s", __FUNCTION__);
// _ivarObject = nil;
// _propertyObject = nil;
}
- (void)assignStuff
{
_ivarObject = [[IvarObject alloc] init];
self.propertyObject = [[PropertyObject alloc] init];
}
@end
int main () {
ArcTest *test = [[ArcTest alloc] init];
[test assignStuff];
test = nil;
NSLog(@"End program");
}