2010-07-08 25 views
3

我創建了一個名爲我的AppDelegate「myDBManager」變量:使用的AppDelegate的變量爲全局變量 - 問題就釋放/保留

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
    MyDBManager *myDBManager; 
} 
@property (nonatomic, retain) MyDBManager *myDBManager; 

@end 

我在大多數其他類使用一個全局變量保存所有我的關鍵應用數據。它只能創建一次,只會在最後死亡。因此,例如,去的myDBManager在AnyOtherClass

@interface AnyOtherClass : UITableViewController { 
    MyDBManager *myDBManager; 
    NSObject *otherVar; 
} 
@property (nonatomic,retain) MyDBManager *myDBManager; 
@property (nonatomic,retain) NSObject *otherVar; 
@end 

//getting the data from "global" myDBManager and putting it into local var of AnyOtherClass 
- (void)viewWillAppear:(BOOL)animated { 
    //get the myDBManager global Object 
    MyAppDelegate *mainDelegate = (MyAppDelegate *)[[UIApplication sharedApplication]delegate]; 
    myDBManager = mainDelegate.myDBManager; 
    } 


- (void)dealloc { 
     [otherVar release]; 
     //[dancesDBManager release]; DO NOT RELEASE THIS SINCE ITS USED AS A GLOBAL VARIABLE! 
     [super dealloc]; 
     } 

這裏是我的問題:雖然AnyOtherClass的其他局部變量,如「otherVar」已經在AnyOtherClass的dealloc方法釋放(始終在線的是,對嗎?),在AnyOtherClass中釋放myDBManager會導致應用程序出錯。

所以我永遠不會釋放本地myDBManager變量在我的應用程序的任何類 - 所有其他本地變量總是釋放 - 它工作正常。 (甚至檢查retainCount)。

我說得對嗎?所有類的局部變量都需要在該類的dealloc中釋放,或者實際上可以,在使用全局變量構造的情況下不要釋放這些變量? (或其他情況?)

非常感謝您的幫助!

回答

2

在您的場景中myDBManager不是全局或局部變量,它是一個自動保留的屬性(標記爲retain)。根據The Objective-C Programming Language: Declared Properties,nonatomic,retain屬性應在dealloc明確發佈。但是,如果您的財產是合成的,您無權訪問支持成員變量,因此您無法在其上調用release;您必須使用屬性設置器將其設置爲nil,它會將release發送到先前的值。你有沒有把myDBManager屬性設置爲AnyOtherClassmyAppDelegatenil

更新:@唐的回答其實是正確的。你沒有調用屬性設置器(self.myDBManager),所以自動保留不會啓動。我將離開我的答案,以便人們可以從我的錯誤中學習。 :-)

2

當你在AnyOtherClass中引用它時,你還沒有保留它,所以它不是你自己發佈的。你直接設置伊娃,所以財產保留不起作用。如果你叫

self.myDBManager = mainDelegate.myDBManager; 

你會保留它,並且在你釋放該類時將不得不釋放它。

但是,如果它是一個全局變量,爲什麼不在AnyOtherClass中以這種方式使用它?當你需要DB管理器時,爲什麼不叫mainDelegate.myDBManager

+0

...因爲使用「mainDelegate.myDBManager」需要「MyAppDelegate * mainDelegate =(MyAppDelegate *)[[UIApplication sharedApplication] delegate];」 而這是太多的文字是可讀的。變量「myDBManager」是「AnyOtherClass」的局部變量,所以我可以很容易地在這個類的所有方法中使用它。 但謝謝你的澄清!所以我永遠不會釋放,如果沒有「self.xx」的ivar JUST被分配! (當然,如果它被分開,我需要釋放 - 但這是另一種情況)是嗎? – user387184 2010-07-08 22:26:14

+0

不,如果您將該屬性聲明爲「retain」,則應始終保留該屬性,然後在dealloc中釋放它。這樣,無論您是直接在課堂上設置還是調用屬性,您都會獲得一致的表現。真的,你應該總是使用'self.property'來確保它按照你的期望行事。但請參閱Franci的答案,詳細解釋何時應該做什麼。 – Don 2010-07-08 22:32:50

+0

要更清楚一點:如果你不使用屬性,你應該改變這個:'myDBManager = mainDelegate.myDBManager;'這個:'myDBManager = [mainDelegate.myDBManager retain];'但我仍然推薦'self.myDBManager = mainDelegate.myDBManager;' – Don 2010-07-08 22:34:37