iPhone:内存管理新手问题

4
我是一个有用的助手,可以翻译文本。
我是iPhone开发的新手,在我的第一个应用程序中跳进去之前进行了大量阅读。所有这些阅读让我明白,正确的内存管理非常重要,所以我想做对事情。
我刚刚完成了我的第一个应用程序,并开始测试它是否有泄漏。有很多:) 我已经更改了代码来解决泄漏问题,然后开始出现BAD_ACCESS异常。现在我的问题是:
  • 我有一个UITextView对象,我们称之为 'utv'。 我看到它的“text”字段定义如下:

    @property (nonatomic, copy) NSString * text;

如果我写下以下代码行:

utv.text = [NSString stringWithString:@"Blabla"];

我不应该担心自动释放池会释放字符串,对吧?因为它使用了copy?

  • 如果它被定义为

    @property (nonatomic, retain) NSString* text;

    我仍然不需要担心自动释放池,因为retain将引用计数增加了1吗?

  • 我能知道自动释放池何时释放我用stringWithString创建的字符串,而不是initWithString吗?

谢谢! Eli


只是一个与主要问题无关的评论。今天我发现了WWDC2010视频会话311:使用Instruments进行高级内存分析。我仍然是一个初学者,它让我更好地理解如何追踪泄漏、废弃的内存以及如何处理内存警告。 - matm
4个回答

3

在我看来,您已经基本回答了自己的问题。如果属性是retain类型,那么新值将在其合成的setter方法中收到retain消息,所以您不必担心它 :)

以下是setter方法之间的代码区别,以帮助您理解它们如何处理内存:

// assign 
property = newValue;

// retain
if (property != newValue) {
    [property release]; 
    property = [newValue retain];
}

// copy 
if (property != newValue) {
    [property release]; 
    property = [newValue copy];
}

谢谢你的回答。我刚刚读了一些相关的问题,看到有人写道 obj = someValueself.obj = someValue 是不同的。为什么呢?这两行代码不都调用了 setter 吗? - Eli Ganem
@Eli - 不,第一个只是分配对象 - 只有 self.obj = someValue 才会调用属性。 - deanWombourne

1
不要以自动释放池或保留计数的方式考虑内存管理。要从是否拥有对象的角度来考虑。如果你拥有它,就要负责释放它。
这两行都创建了保留属性:
@property (nonatomic, copy) NSString *text;
@property (nonatomic, retain) NSString *otherText;

复制只意味着保留一个副本,而不是原始副本。这两个属性都是内存管理的,因此在正常使用中,您不必担心保留或释放。

self.text = string1; // this retains a copy of string1
self.text = string2 // this releases the copy of string1 and retains the copy of string2
self.text = nil; // this releases the copy of string2

你拥有self.text和self.otherText,所以你需要在dealloc中释放它们。
如果你没有alloc、new、copy或retain一个对象,那么你就不拥有它。如果你不拥有它,但是你需要保证它在运行循环结束后仍然存在,那么通过retain来声明所有权。

0

你是正确的。当属性设置为retain或copy时,你不应该关心autorelease池。你不会知道何时NSAutoreleasePool会释放你的字符串,但你可以安全地假设你可以在声明它的同一方法中自由使用它。每个线程都应该有自己的NSAutoReleasePool,它可以随时被清空,但通常在每个运行循环的开始时被清空。


你不能假设自动释放将何时触发。 - Jordan
我知道,我告诉他的是在同一个方法中使用autorelease对象是安全的。 - Joe

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接