NSString的内存分配/释放

时间:2011-06-09 05:36:13

标签: iphone objective-c memory-management

我有一个采用MKAnnotation协议的类。除了两个“标题和”副标题“要实现的方法之外,我还想添加两个NSStrings,一个代表典型美国地址中的每一行。例如:

addressLine1 = 123 street
addressline2 = northridge, ca 91326

我的副标题方法目前看起来像:

- (NSString *)subtitle {
    NSMutableString * ret = [NSMutableString stringWithCapacity:kDefaultStringCapacity];
    if (streetAddress) {
        [ret appendString:streetAddress];
        addressLine1 = [[NSString alloc] initWithFormat:streetAddress];
    }
    ... more code

我何时会发布addressLine1?因为它是我声明的属性(非原子,保留),我已经在我的dealloc方法中释放它。或者我是使用类方法还是自动释放字符串?感谢。

2 个答案:

答案 0 :(得分:3)

如果您autorelease address1,您将失去对象的所有权,并且没有任何其他所有者,它将被取消分配。如果你正在做的话,你需要autorelease

self.address1 = [[NSString alloc] initWithString:streetAddress];

这是错误的,因为您将获得两次所有权并仅在dealloc方法中放弃一次。正确的方式就是,

self.address1 = [[[NSString alloc] initWithString:streetAddress] autorelease];

上面的直接赋值只有在为其赋值一次时才有效。如果要再次分配,您将丢失对早期引用的引用,并且您的应用程序将泄漏。因此,在此处使用属性访问器将是一个很好的过程,这将确保取消分配较旧的值。

字符串的另一个问题是你要复制它们,因为你不希望它们在赋值后变异,所以属性应该被声明为@property (nonatomic, copy)而不是它现在。

答案 1 :(得分:2)

如果您的属性为(nonatomic, retain),那么如果您没有明确addressLine1,则会泄漏release资源。一旦你完成它我就会释放它。然后,您应该按照目前的dealloc方法发布该属性。

与问题有点无关,但仍然相关的是,只要您有一个实现NSCopying协议的对象,例如NSString,在这种情况下,您应该使用copy代替retain。这是一个提供一些很好信息的SO question