簡體   English   中英

在ARC下,卸載viewcontroller時需要為所有強成員設置nil嗎? 這是必須的嗎?

[英]Under ARC, need to set nil to all the strong member when unload the viewcontroller? Is that a must?

假設我有一個這樣的視圖控制器:

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

@end

並在我設置的viewDidLoad函數中

a = [[NSSString alloc] init];

在另一個ControllerB中,

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

控制器的成員會被釋放嗎?

是的,當取消分配controllerA時,將釋放a指向的字符串。 您不需要將其設置nil

轉換到ARC發行說明目前是查找有關使用ARC的更多信息的地方。 它的一個重點是,如果您的類需要執行釋放實例變量時釋放實例變量以外的任何操作,您可能仍需要自定義-dealloc

您永遠不需要在ARC中將變量設置為nil,除非您希望盡快確保其解除分配(即非ARC代碼下的[myObject release])。 取消分配對象后,將自動釋放所有iVar。

在使用ARC和Zombies時,iOS 5中存在一個眾所周知的錯誤,它可以阻止ivars的發布: 技術問答QA1758

否則,ivars將自動釋放。

更新2:

在我的iOS 5項目今天早上花了幾個小時診斷和記錄ivars發布失敗的幾個小時后,我發現如果僵屍打開並在iOS 5上運行,ARC項目中不會發布實例變量。我非常獨立地用這些非凡的發現更新了我的答案, Calin向我指出這是眾所周知的行為。 技術問答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

當我使用dealloc方法中的=nil語句注釋掉時,我在控制台上看到以下內容:

2012-07-12 10:33:33.644 test4 [36045:11903] - [ArcSimpleTestViewController dealloc]

當我在dealloc取消注釋=nil語句時,我看到以下內容:

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");
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM