2011-11-16 39 views
0

我最近在我的一個類中重寫了一些代碼,這給了我一個NSString的錯誤。以下是我現在有:爲什麼我必須保留/複製這個NSString?

我的類的頭:

@interface MyViewController : UITableViewController { 
    NSString *myString; 
} 

@property (nonatomic, retain) NSString *myString; // Or copy instead of retain. 

@end 

並採取了一些方法:

- (void)viewDidLoad { 
    myString = @"This is"; 

    if (something) { 
     myString = [NSString stringWithFormat:@"%@ a string.", myString]; // *1 
    } 

    [myString retain]; // <-- Why do I have to retain/copy here? 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (indexPath.row == 0) { 
     /* Some code for creating a UITextView called myTextView */ 
     // ..and then setting the text property: 
     myTextView.text = myString; // <-- Crashes here if I don't retain/copy in viewDidLoad. 
    } 
} 

一些調試我算了一下,保留/複製的NSString之後。

爲什麼我必須在viewDidLoad中保留/複製NSString,如果以後要使用它的話?

此外,我注意到,如果我刪除標記* 1的行,我不必保留/複製。

回答

1

如果使用合成的setter方法給變量賦值,它會自動保留NSString爲您提供:

if (something) { 
    self.myString = [NSString stringWithFormat:@"%@ a string.", myString]; // *1 
} 
+0

謝謝,這解決了它。 – matsr

1

一種方法可以讓你更好的理解,這將是一個下劃線前綴您的私人屬性_myString並將你的屬性保存爲myString - 這可以很容易地計算出正在使用的屬性或屬性。

由於您似乎只是在您的班級中使用該值,我會質疑爲什麼您有一個屬性,因爲我認爲這是造成混淆的根源。

如果您已經放置了前綴,那麼您將始終知道_myString在分配給它時需要保留,而myString將自動保留。

* 1處的行正在用新字符串替換myString的值,出於某種原因,在處理第二個方法中的代碼之前,此值是自動釋放的。我不記得確切的原因,但我認爲這不會發生在第一個作業上,因爲您創建了一個字符串文字,其中@「This is」不是自動發佈的。

我希望這會有所幫助。

0

您可以使用保留的屬性訪問,這將釋放/保留自動

- (void)viewDidLoad { 
    self.myString = @"This is"; 
    if (something) { 
     self.myString = [NSString stringWithFormat:@"%@ a string.", myString]; // *1 
    } 
    // no need to retain 
} 

的原因,它不會崩潰,當你刪除標線* 1是因爲MyString的是在@"This is"仍然指向,這是一個在整個程序的整個過程中,它都存儲在內存的一個角落,並且永遠不會被破壞,因此內存位置仍然有效。