假设我有一个这样的视图控制器:
@interface ControllerA : viewcontroller{
NSString * __strong a;
}
@end
并在viewDidLoad
函数中设置
a = [[NSSString alloc] init];
在另一个ControllerB中,
{
ControllerA * controllerA = [[ControllerA alloc] init];
}
controllerA的成员会被释放吗?
答案 0 :(得分:5)
是的,a
指向的字符串将在controllerA
解除分配时释放。您无需自己将其设置为nil
。
Transitioning to ARC Release Notes目前是查找有关使用ARC的更多信息的地方。它的一个重点是,如果您的类需要执行任何操作而不是在实例被释放时释放实例变量,您可能仍需要自定义-dealloc
。
答案 1 :(得分:4)
除非您希望尽快确保其释放(即非ARC代码下的[myObject release]),否则您永远不需要在ARC中将变量设置为nil。取消分配对象后,将自动释放所有iVars。
答案 2 :(得分:2)
在使用ARC和Zombies时,iOS 5中存在一个众所周知的错误,可以防止ivars被释放:Technical Q&A QA1758。
否则,ivars将自动释放。
答案 3 :(得分:1)
更新2:
我花了几个小时诊断并记录今天早上在我的iOS 5项目中发布的ivars失败的几个小时后,我发现如果僵尸打开并在iOS 5上运行,则ARC项目中不会发布实例变量关于用这些非凡的发现更新我的答案,相当独立,Calin向我指出这是众所周知的行为。 Technical Q&A QA1758。谢谢Calin!
我的示例项目位于https://github.com/robertmryan/arc-problem-project
<强>更新强>
我之前声称这是不正确的,除非您将它们设置为nil
,否则不会取消分配变量和属性。我提供了以下代码作为示例。这是从一个真正的ARC测试项目中获取的,我甚至用另一个视图控制器重新创建它,除了下面的代码确认之外绝对没有。在得到了当之无愧的反对意见之后,我将这个代码示例放在一个新项目中,并将ivar解除分配,应该是这样。
所以它必须是有问题的项目。我已经完全取消了该项目的所有内容,除了下面的代码(以及执行推送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 dealloc]
对于我的撤回,当我将相同的代码放在一个新项目中时,我会看到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");
}