5

假设我有一个这样的视图控制器:

@interface ControllerA : viewcontroller{
    NSString * __strong a;
}

@end

viewDidLoad我设置的功能中

a = [[NSSString alloc] init];

在另一个 ControllerB 中,

{
    ControllerA * controllerA = [[ControllerA alloc] init];
}

controllerA的成员会被释放吗?

4

4 回答 4

5

是的, 指向的字符串a将在释放时controllerA被释放。你不需要nil自己设置。

过渡到 ARC 发行说明目前是查找有关使用 ARC 的更多信息的地方。它提出的一个重要观点是,如果您的类需要在释放实例时释放实例变量之外-dealloc的任何事情,您可能仍然需要自定义。

于 2012-07-12T04:37:39.767 回答
4

你永远不需要在 ARC 中将变量设置为 nil,除非你想确保尽快释放它(即非 ARC 代码下的 [myObject release])。当对象被释放时,所有的 iVar 都会被自动释放。

于 2012-07-12T04:34:40.430 回答
2

在使用 ARC 和 Zombies 时,iOS 5 中有一个众所周知的错误,它会阻止 ivars 被发布:技术问答 QA1758

否则,ivars 将被自动释放。

于 2013-02-28T14:49:14.740 回答
1

更新 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");
}
于 2012-07-12T13:25:59.887 回答