[英]should I set strong IBOutlet to nil when receive memory warning under ARC?
[英]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.