2011-11-16 84 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"仍然指向,这是一个在整个程序的整个过程中,它都存储在内存的一个角落,并且永远不会被破坏,因此内存位置仍然有效。

相关问题