16

我是新的Objective-C,我想了解內存管理是否正確。什麼時候釋放了一個自動釋放的對象?

通過蘋果閱讀優秀
Memory Management Programming Guide for Cocoa後,我唯一擔心的是,當 實際上是一個自動釋放的對象在iPhone/iPod的應用程序發佈。我的理解是在運行循環的末尾。但是什麼定義了應用程序中的運行循環?

所以我想知道下面的一段代碼是否正確。假設一個物體

@implementation Test 

- (NSString *) functionA { 
    NSString *stringA; 
    stringA = [[[NSString alloc] initWithString:@"Hello"] autorelease] 
    return stringA; 
} 

- (NSString *) functionB { 
    NSString *stringB; 
    stringB = [self functionA]; 
    return stringB; 
} 

- (NSString *) functionC { 
    NSString *stringC; 
    stringC = [self functionB]; 
    return stringC; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSString* p = [self functionC]; 
    NSLog(@"string is %@",p); 
} 

@end 

此代碼是否有效?

從蘋果的文字我明白的NSString返回從泛函是在functionB範圍內有效。我不確定它是否在函數CviewDidLoad中有效。

謝謝!

回答

17

是的,你的函數是有效的,並且使用正確的Cocoa約定來返回對象來保留/釋放/自動釋放/複製。

要在應用程序的main()函數中回答有關runloop是什麼的問題,請調用UIApplicationMain()。你可以想像UIApplicationMain看起來是這樣的:

void int UIApplicationMain (int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName) { 
    UIApplication *app = /* create app using principalClassName */; 
    [app setDelegate:/* create delegate using delegateClassName */]; 
    while (![app shouldTerminate]) { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     event = [app getNextEvent]; 
     [app dispatchEvent:event]; 
     [pool drain]; 
    } 
} 

這while循環類似於什麼的UIKit究竟是幹什麼,並通過while循環每次出行是想通過runloop一趟,那裏的功能getNextEvent塊等待一些事件發生。所有的方法通常都是從dispatchEvent之類的東西中調用的。您可以嘗試在其中一個方法中設置斷點,如IBAction,並在頂部查看調試器調用堆棧以查看處理事件和runloop的UIKit方法的名稱。由於您的每個方法都是在while循環中調用的,因此每次在對象上調用autorelease時,都會將該對象添加到運行循環中的outter池中。當前事件完成調度時,池被耗盡,並且這些對象最終被髮送釋放消息。

最後一個註釋。可以有多個autorelease池,並不總是在事件循環結束時。有時你可能會在事件循環中一次分配數以萬計的對象。發生這種情況時,您可以在自己的方法中設置其他內部自動釋放池,以將autorelease對象的數量保持在autorelease池中。自動釋放池可以堆疊。

+0

我是否正確理解如果我沒有創建任何autorelease池,所有自動發佈的變量都將保留在內存中直到應用程序未關閉? – Burjua 2011-02-24 20:30:26

+0

類型,系統框架在UIApplicationMain()方法的主線程堆棧頂部爲您創建一些自動釋放池。但是,如果您創建了自己的線程,並且沒有創建池,那麼是的,這些對象會泄漏。在這種情況下,autorelease方法會記錄到控制檯。 – 2011-02-24 21:00:54

+0

好的,謝謝,但這很奇怪,使用返回自動釋放對象並且不釋放它們的構造函數是正常的做法,但它實際上與有內存泄漏(分配內存直到應用程序關閉)相同。或者我不明白什麼? – Burjua 2011-02-24 21:47:22

0

該代碼沒有問題。它將按照您的預期進行編譯和運行。

functionA返回的NSString對象仍然返回時有效的,因爲它被流傳下來的堆到下一個傢伙(functionB)誰現在是保持它的軌道。

+3

「通過堆棧」可能不是短語的最佳選擇,因爲它意味着堆棧用於返回值,但並非總是如此。 – 2010-03-23 12:41:58