2010-06-02 45 views
4

我很難在UIViewController中的幾個方法,但首先我會說我認爲他們的意思(忽略接口生成器,因爲我不使用它):iPhone開發 - viewDidUnload子視圖

-init:初始化不需要在低內存情況下釋放的非視圖相關的東西(即不是不容易重新創建的對象或對象)。
-loadView:創建視圖設置[self view]屬性。
-viewDidLoad:創建所有其他視圖元素
-viewDidUnload:在-viewDidLoad中創建的發佈對象。
didReceiveMemoryWarning:低內存的情況,釋放不必要的東西,如緩存的數據,如果這個視圖沒有超級視圖然後[super didReceiveMemoryWarning]將繼續釋放(卸載)視圖,並呼籲-viewDidUnload
-dealloc:釋放一切
-viewWillAppear:-viewDidAppear:-viewWillDisappear:-viewDidDisappear:不言自明的,沒有必要,除非你想回應(做某事)這些事件。

我不確定一些事情。首先,蘋果文檔說,當調用-viewDidUnload時,視圖已經發布並設置爲零。

  1. 請問-loadView會再次調用以重新創建視圖嗎?
  2. 我在-viewDidLoad中創建了一些東西,我沒有製作ivar/property,因爲沒有必要,它會被視圖保留下來(因爲它們是子視圖)。所以當視圖被髮布時,它也會釋放這些,對吧?當視圖發佈時,它是否會發布其所有子視圖?因爲我在-viewDidLoad中創建的所有對象都是子視圖[self view]。所以如果他們已經發布了,爲什麼要在-viewDidUnload再次發佈它們?我可以理解在這些方法中加載和卸載視圖時必要的數據,但正如我所問,爲什麼釋放子視圖,如果它們已經發布?

編輯:閱讀其他問題後,我想我可能會得到它(我的第二個問題)。在我只使用局部變量的情況下,進行分配,使其成爲子視圖並釋放,其保留計數爲1(將其作爲子視圖添加),因此視圖釋放時也是如此。現在對於ivars指向它們的視圖元素,我沒有使用屬性,因爲沒有外部類需要訪問它們。但現在我認爲這是錯誤的,因爲在這種情況下:

// MyViewController.h 
@interface MyViewController : UIViewController { 
    UILabel *myLabel; 
} 

// MyViewController.m 
. . . 
- (void)viewDidLoad { 
    myLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 40, 10)]; 
    [myLabel setText:@"Foobar"]; 
    [[self view] addSubview:myLabel]; 
} 

- (void)viewDidUnload [ 
    // equivalent of [self setMyLabel:nil]; without properties 
    [myLabel release]; 
    myLabel = nil; 
} 

在這種情況下,該標籤將被髮送-release消息後,它被釋放,因爲伊娃沒有保留它(因爲它不一個屬性)。但是對於一個財產,保留數將是兩個:保留它的視圖和財產。然後在-viewDidUnload它將被釋放。所以最好總是使用這些東西的屬性,我說得對嗎?或不?

回答

2

-loadView再次調用重新創建視圖後?

是的,只要有人訪問view屬性。

當視圖被髮布時,它會釋放它的所有子視圖嗎?

是的。

至於你不要以後需要的標籤,這樣的東西,通常的做法是簡單地釋放他們,你將它們連接到視圖後:

UILabel *foo = [[UILabel alloc] init…]; 
[self.view addSubview:foo]; 
[foo release]; 

在這種情況下,標籤將被釋放時,該視圖被釋放。


你的例子中的內存管理很好。當你的alloc標籤,其retainCount跳到1,視圖保留它(retainCount = 2),然後視圖被解除分配並釋放標籤(rc = 1),然後你最終自己釋放標籤(rc = 0,dealloc )。

爲了使事情更加清楚 - 變量myLabel沒有明確保留標籤,但是您仍然擁有它,因爲您已分配它。這是可可內存管理的基本規則之一:alloc +1,retain +1,release -1,autorelease -1稍後。

實施例:

@property(retain) UILabel *foo; 
self.foo = [[UILabel alloc] init…]; 

這將是一個泄漏,因爲標籤的alloc期間獲得一個1和另一個1在設定器用於foo屬性生成。閱讀Cocoa內存管理指南或Scott Stevenson’s Objective-C tutorial。 Cocoa的內存管理非常簡單,經過一番思考後,你應該在所有情況下都非常舒適。

+0

謝謝,我明白了。但是,我是否正確地使用屬性,我編輯的文章的最後部分? – mk12 2010-06-02 15:13:54

+0

什麼我問的是隻是爲了證實這一點:除了卸載,您將在'-viewDidLoad',重新創建數據'-viewDidUnload'是解除性('[個體經營的setProperty:無]'),其仍保留的子視圖' [self view]','[self view]'已經發布,所以可以解除分配。我對嗎? – mk12 2010-06-02 15:17:17

+0

但我認爲那裏的例子有代碼不起作用?因爲成員變量myLabel從不保留UILabel(只有視圖),但它仍然在'-viewDidUnload'中釋放它。或者你是在談論我之後描述的內容?我想要決定的是我應該總是使用像這樣的東西(我需要一個成員變量)的屬性? – mk12 2010-06-02 15:26:33