2011-01-29 310 views
0

我是iPhone編程新手。我創建了一個基於窗口的應用程序。以下是我的代碼:iphone應用程序崩潰

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    UILabel *myLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(50, 200, 200, 80)]; 
    myLabel1.text = @"Prasad"; 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [myLabel1 release]; 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [window makeKeyAndVisible]; 
    return YES; 
} 

Q1。當我釋放mylabel1時,在release語句之後的NSLog語句仍然會打印retainCount爲1,而理想情況下它應該打印0.此外,應用程序運行非常好。

現在考慮下面的代碼:(這類似於上面的代碼中,除了加入一個的NSLog聲明:的NSLog(@ 「Bingoooooooo Memeory被釋放」);)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
    UILabel *myLabel1 = [[UILabel alloc] initWithFrame:CGRectMake(50, 200, 200, 80)]; 
    myLabel1.text = @"Prasad"; 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [myLabel1 release]; 
    NSLog(@"Bingoooooooo Memeory Released"); 
    NSLog(@"myLabel retain Count: %d\n", [myLabel1 retainCount]); 
    [window makeKeyAndVisible]; 
    return YES; 
} 

現在我的查詢,
1 。當我運行上面的代碼時,應用程序在打印NSLog(@「Bingoooooooo Memeory Released」)後崩潰;爲什麼應用程序只是通過添加NSLog(@「Bingoooooooo Memeory Released」)語句而崩潰,而在第一個代碼中,應用程序不會崩潰。

+0

Prazi,請花時間在問題中正確地設置代碼的格式,那麼很有可能有人能夠幫助您。 –

+0

發送您的應用程序崩潰報告。 – Tirth

+2

如果'retainCount'曾經返回零,那麼奇點就會實現,宇宙就會結束。至少,它會用於你的應用程序。 – bbum

回答

1

的文檔-retainCount有如下警告:

重要:這種方法通常是在調試內存管理問題沒有價值的。因爲任何數量的框架對象都可能保留了一個對象以保存對它的引用,同時autorelease池可能在對象上保存了任意數量的延遲發佈,所以很難從此獲得有用的信息方法。

而且,各種其他的答案大約保持在堆棧溢出計數說,不靠-retainCount


這就是說,回答你的問題:

Q1。當我釋放mylabel1,繼發佈聲明的NSLog聲明仍然打印retainCount爲1,而理想情況下,應打印0

讓我們考慮你的對象是不是在一個自動釋放池。如果對象保留計數1並收到release消息,則它將被解除分配。減少一個釋放對象的保留計數有什麼意義?運行時沒有這樣做,因爲它是一個毫無意義的操作,因爲對象已經不存在了。

1.當我運行上面的代碼時,應用程序在打印NSLog(@「Bingoooooooo Memeory Released」)後崩潰了;爲什麼應用程序只是通過添加NSLog(@「Bingoooooooo Memeory Released」)語句而崩潰,而在第一個代碼中,應用程序不會崩潰。

首先,請注意,由於myLabel1未被其他對象/代碼所有,因此當您發送[myLabel1 release]時,它將被釋放。如果您將更多消息發送到解除分配的對象(例如[myLabel1 retainCount]),您的代碼可能會崩潰,所以不要這樣做。

當一個對象被釋放時,對象佔用的內存被標記爲可用。根據隨後的指令,先前由對象佔用的內存區域可能會或可能不會被重寫。在重寫之前,可以引用解除分配的對象 - 它是一個鬼對象,並且根本不可靠。在你的情況下,添加另一個NSLog()指令或其他因素會導致該內存區域被重寫。

4

首先,永遠不要看retainCount。它不可靠,並受很多內部因素的影響。代碼的第二個版本會導致崩潰,因爲: 1)您創建一個標籤,使其保留計數爲1 2)您釋放它以使其保留計數爲0 3)您向其發送消息。由於其保留計數爲0,因此它已被釋放,所以應用程序崩潰。

不知道爲什麼第一個版本不崩潰

+0

@Prazi查看Dave Delong的答案http://stackoverflow.com/questions/4636146/when-to-use-retaincount/4636477#4636477 – Robin