2009-10-22 31 views
12

我有一個靜態方法,它創建類的一個實例並將其放入靜態變量中。我想知道在這種情況下正確的內存管理方式是什麼。Objective-C/iPhone內存管理靜態變量

你不能把它在的dealloc法,因爲它雖然可以訪問靜態變量,得到新版本發佈也將釋放sharedInstance所創建的任何實例方法。

我猜有可能是創建一個靜態的破壞方法,這將manualy釋放內存,並可以通過從appWillTerminate用戶調用的一個選項,但似乎有點奇怪。

所以,再次,問題: 什麼是釋放靜態變量的正確方法?


// MyClass.m 
#import "MyClass.h" 

static MyClass *myClass; // How to properly do memory management 

@implementation MyClass 

+ (MyClass *)sharedMyClass { 
    if (myClass == nil) myClass = [[MyClass alloc] init]; 
    return myClass; 
} 
@end 

回答

8

您可以不釋放它們,這是正常的,因爲應用程序正在關閉。 iPhone上的Cocoa已經做到了這一點,它並沒有完全刪除所有東西,它只是讓應用程序被吹走。

或者你可以從appWillTerminate或其他一些關機功能將其刪除。

+3

需要注意的是,如果你有一個單身一件事可能是一個好主意,做的是有某種清理的方法,也可以通過應用程序委託調用當它得到一個低內存警告。你甚至可以在那個時候轉儲整個靜態對象,並且如果創建不是太昂貴的話就讓它重新創建。 – 2009-10-22 16:10:32

7

你要看看"Creating a Singleton"在iPhone開發中心,瞭解如何正確地實現這種模式。你不會釋放你的單例,只是在應用程序退出時讓它死掉。

另外,如果你是多線程的,你可能會想包裝在@synchronize(個體經營)即頁頭{}

以下是全文:

基金會的一些類和 Application Kit創建單例 對象。在「嚴格」實施中, 單個實例是目前 過程中一個類的唯一允許的 實例。但你也可以在 更 靈活的單執行該工廠方法總是返回 相同的實例,但你可以 分配和初始化附加 instances.The的NSFileManager類適合 後者的模式,而 的UIApplication適合前任的。當您要求 UIApplication的實例時,它會向您傳遞一個 對唯一實例的引用, 如果 尚不存在,則會分配並初始化它。

單體對象充當一種 控制中心,指揮或 協調 類的服務。你的類應該產生 單實例,而不是 多個實例時,有 概念上只有一個實例(如 用,例如,NSWorkspace)。您 使用單實例而不是 工廠方法或功能時,它 可以想象,有可能是 多個實例一天。

要創建一個單獨作爲 當前進程一類的唯一 允許的情況下,你需要有一個類似於清單 2-15的 實現。此代碼執行以下操作:

聲明單個對象的一個​​靜態實例並將其初始化爲 nil。在 的類工廠方法中,只有在靜態實例爲nil的情況下,該類纔會生成類的實例,但會生成 類(類似於 「sharedInstance」或「sharedManager」) 。 重寫allocWithZone:方法來 確保另一個實例是不是 分配,如果有人試圖分配 和初始化 類的實例,而不是直接使用 類工廠方法。相反,只有 返回共享對象。執行 基本協議方法 copyWithZone:,釋放,保留, retainCount,並autorelease做 適當的事情,以確保單身人士 狀態。 (這些 方法的最後四個適用於內存管理代碼, 不是垃圾收集代碼。) 清單2-15嚴格執行 單身靜態MyGizmoClass

*sharedGizmoManager = nil; 
+ (MyGizmoClass*)sharedManager { 
    if (sharedGizmoManager == nil) { 
     sharedGizmoManager = [[super allocWithZone:NULL] init]; 
    } 
    return sharedGizmoManager; } 
+ (id)allocWithZone:(NSZone *)zone { 
    return [[self sharedManager] retain]; } 

- (id)copyWithZone:(NSZone *)zone { 
    return self; } 

- (id)retain { 
    return self; } 

- (NSUInteger)retainCount { 
    return NSUIntegerMax; //denotes an object that cannot be released } 

- (void)release { 
    //do nothing } 

- (id)autorelease { 
    return self; } 

如果您想要一個單例實例(創建並由 方法控制的 ),但也有能力 根據需要創建其他實例 通過分配和初始化, 不覆蓋allocWith Zone:和 之後的其他方法,如 清單2-15所示。


UPDATE:現在有一個更簡單的方法來創建一個單獨

+ (MyClass*)sharedInstance 
{ 
    static MyClass* _sharedInstance = nil; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
    _sharedInstance = [[MyClass alloc] init]; 
    }); 

    return _sharedInstance; 
} 

使用這種新的風格,你不必擔心@syncronize或重寫內存管理方法。

1

靜態變量或類留在你的應用程序

因此,如果未使用的內存,直到終身然後進行

Your_variable = nil; 

同時宣佈使用靜態_datatype變量=零; 這有助於在初始化..和內存管理

///************************** 
// MyClass.m 
#import "MyClass.h" 

static MyClass *myClass = nil; 

@implementation MyClass 

+ (MyClass *)sharedMyClass { 
    if (myClass == nil) 
      myClass = [[MyClass alloc] init]; 
    return myClass; 
} 

@end