【问题标题】:Why do I have to retain/copy this NSString?为什么我必须保留/复制这个 NSString?
【发布时间】:2011-12-30 17:56:51
【问题描述】:

我最近在我的一个类中重写了一些代码,这给了我一个 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 的行,我就不必保留/复制。

【问题讨论】:

    标签: ios memory-management nsstring copy retain


    【解决方案1】:

    如果你使用综合的setter方法给变量赋值,它会自动为你保留NSString

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

    【讨论】:

      【解决方案2】:

      让您更好地理解这一点的一种方法是在您的私有属性前加上下划线 _myString 并将您的属性保留为 myString - 这样可以很容易地确定正在使用的属性 - 属性或属性。

      由于您似乎只在您的课程中使用该值,我会质疑您为什么有一个属性,因为我认为这是造成混乱的根源。

      如果您已经放置了前缀,那么您将始终知道 _myString 在分配时需要保留,而 myString 将自动保留。

      *1 处的行正在用新字符串替换 myString 的值,并且由于某种原因,在处理第二个方法中的代码之前,该值会自动释放。我不记得确切的原因,但我认为第一次分配不会发生这种情况,因为您使用 @"This is" 创建了一个字符串文字,它不是自动释放的。

      我希望这会有所帮助。

      【讨论】:

        【解决方案3】:

        您可以使用将自动释放/保留的保留属性访问器

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

        删除标记为 *1 的行时它不会崩溃的原因是 myString 仍然指向 @"This is",这是一个垃圾,它在程序的整个持续时间内都存在于内存的一个角落,并且永远不会已销毁,因此该内存位置仍然有效。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-22
          相关资源
          最近更新 更多