2010-01-31 34 views
1

我有一個關於實例變量如何工作以及何時使用@property的問題。這裏是我正在使用的示例接口文件關於ivars和@財產在iPhone上的問題

@interface PackageModel : NSObject { 
    NSString *tracking; 
    NSString *carrier; 
    NSString *status; 
    NSMutableDictionary *events; 

    // Connection ivars 
    NSMutableData *receivedData; 

    // Parsing ivars 
    int tagLevel; 
    NSMutableArray *tagTree; 
    NSString *parentTag; 
    NSString *currentTag; 
} 

@property (nonatomic, retain) NSMutableData *receivedData; 

- (id)initWithTrackingString:(NSString *)string; 
- (void)getPackageDataWithEvents; 
- (void)printMe; 

@end 

如何在文件的代碼中訪問這些文件。我可以訪問跟蹤,載體和狀態在這個類的方法只是通過使用類似

tracking = [[NSString alloc] initWithString:@"Hello World"]; 

此外,變量需要放在dealloc的是什麼?只有我在@ property/@綜合中的變量?或者我需要釋放dealloc方法中的所有實例變量。

我只是尋找一些關於實例變量如何在Objective-C中工作的說明。謝謝。

回答

3

@property聲明不過是編譯器生成的getter和setter方法。而已。只是方法。顯然,你必須得到並設置,所以我們創建了與吸氣劑和吸附劑配合使用的伊娃。另外,在上述的例子中,編譯器在生成:

- (NSMutableData *) receivedData; 
- (void) setReceivedData:(NSMutableData *)newReceivedData; 

吸氣劑返回在receivedData實例變量的值,以及設置器改變了receivedData實例變量的值。

(旁註:與64位運行時,你可以跳過聲明實例變量,但我還是喜歡把它只是要明確)

至於你應該在你的dealloc方法做什麼,您需要釋放已編輯的實例變量retain ed或copy ed。因此,在您的示例中,您需要在dealloc方法中執行[receivedData release];,因爲當您設置receivedData伊娃時,您保留了新值(這是retain@property行的含義)。如果您在@property聲明中未指定retaincopy,則它默認爲assign,您不必執行任何操作。除此之外,您需要釋放您保留的任何其他實例變量(即,不通過@property (retain)設置器)。

爲了您的最後一個問題,是的,你可以這樣做:

tracking = [[NSString alloc] initWithFormat:@"Hello, %@!", @"world"]; 

裏面自己的類,你必須自己所有的實例變量直接訪問(和你的超類的任何保護,公衆的ivars)。

+0

現在,我已經定義了currentTag和parentTag,我將通過currentTag = qName將它們設置在NSXMLParser委託方法中。我不需要在dealloc中釋放它們,因爲它們只是指向其他字符串的指針,對嗎?但是,如果我讓他們@特性,我需要釋放他們的權利? – rickharrison 2010-01-31 22:38:49

+0

rickharrison:「@財產」與你是否擁有該物品無關。無論你如何擁有它,都沒關係。如果你擁有它,你必須釋放它。請參閱內存管理規則:http://developer.apple.com/mac/library/documentation/General/Conceptual/DevPedia-CocoaCore/MemoryManagement.html – 2010-02-01 03:43:00

0

使用@ property/@ syntehsize的一個優點是它促使您爲ivars使用訪問器方法。這有助於您更好地進行內存管理。在iPhone上,有兩個重要原因讓您知道保留計數:1.保持內存使用量不變。 2.避免崩潰。當你直接訪問ivars時,你會冒着忘記保留一個變量的風險,然後稍後再去訪問它,以便發現它已被釋放。或者相反,你忘了釋放一個變量,並且很快你創建了太多的內存,iPhone操作系統告訴你的應用程序終止。

使用存取方法,即使在類中也是一個好主意。我通常直接設置ivars的唯一地方是在類的init方法中。我通常也會在dealloc方法中釋放所有的ivars。

1

哎呀,這是一個非常廣泛的問題。我強烈建議你閱讀蘋果的Objective-C Primer和他們的full reference to the language

作爲初學者,您問:「我如何在文件代碼中訪問這些文件?」你不指定哪個文件。在PackageModel@implementation內部,您可以像跟蹤示例中那樣簡單地引用實例變量。你不能從其他類輕鬆訪問它們。

但是,如果你讓他們@properties@synthesize他們,你可以在類本身中訪問他們像self.tracking。此外,你現在也可以從其他類訪問它們。

PackageModel *model = [[PackageModel alloc] init]; 
model.receivedData = [NSMutableData data]; 

這些屬性的另一個優點是它們可以爲你處理內存管理。當正確完成時,你真的不需要擔心保留和釋放非常多。您的PackageModel類中的receivedData屬性將在分配新數據之前自動釋放任何先前保留的對象。這是光榮的。發生這種情況是因爲編譯器自動'合成'setters和getters,然後通過點運算符調用它們以進行訪問。

最後一點需要注意的是,這些設置者和獲取者會被@synchronize塊自動保護,以確保操作以原子方式發生(並且第二個線程無法中途中斷活動)。這在iPhone上基本不需要,並且會產生相當大的開銷,所以除了讀/寫權限和內存管理方案之外,您還應該聲明所有屬性爲nonatomic。不包括

1

東西是你的代碼的最後一行可能是:

tracking = @"Hello World"; 

的「@」基本上是創建字符串對象爲您服務。