iOS objective-c返回对象可用性/范围

时间:2011-02-02 10:48:29

标签: objective-c ios memory-management

我已经阅读了苹果文档,断言我正在正确地进行内存管理,但提出了一些问题。

问题1:

他们将此代码段展示为错误:

in obj implementation:
- (NSString *)method1 {
    NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];
    return string;
}

... later ...

NString* myString = [obj method1];
NSLog("%@", myString);
[myString release];

Apple Doc

You own the string returned by alloc, but lose the reference to it before you get a chance to relinquish ownership. Following the memory management rules, this would result in a memory leak, since the caller has no indication that they own the returned object.

由于我正在处理释放先前已分配的对象,因此没有内存泄漏,对吧? “失去对它的引用”是什么意思?

仅关于apple的内存管理建议(调用者没有表明他们拥有返回的对象)这是错误的,或者这在技术上也是错误的?

问题2:

这是关于自动释放的对象可用性:

示例代码:

in obj1 implementation:
- (NSString *)methodA {
    NSString *string = [[NSString alloc] initWithFormat:@"%@ %@", firstName, lastName];
    return [string autorelease];
}

in obj2 implementation:
- (NSString *)methodB:(NSString *)inputString {
    NSLog("%@",inputString)
    //*other call of methods with arg inputString*//
}
... later ...

NString* myString = [obj1 methodA];

[obj2 method2:myString];

在我的函数调用后多远(或深)obj1返回的自动释放对象将可用。关于苹果的文档“自动释放对象将在其可变范围内可用”。我应该在某个时候保留它吗?

2 个答案:

答案 0 :(得分:4)

  

Q1:仅关于Apple的内存管理建议(调用方没有表明他们拥有返回的对象)这是错误的,或者这在技术上也是错误的?

从技术上讲,这是正确的,因为您在使用后释放myString。但是,如果您按照Apples guidelines for method naming强烈推荐),这显然是错误的:

  

您拥有自己创建的任何对象。   您使用名称以“alloc”或“new”开头或包含“copy”的方法“”创建“对象(例如,alloc,newObject或mutableCopy)。

method1不包含createallocnewcopy - 因此根据指南,调用者不拥有该对象并且不会不得不释放它。

  

Q2:我的函数调用后多远(或深)obj1返回的自动释放对象将可用。关于苹果的文档“自动释放对象将在其可变范围内可用”。我应该在某个时候保留它吗?

自动释放的对象将处于活动状态,直到最近的自动释放池耗尽,请参阅Autorelease Pools

  

自动释放池是NSAutoreleasePool的一个实例,它“包含”已收到自动释放消息的其他对象;当自动释放池被释放时,它会向每个对象发送一条释放消息。可以将对象多次放入自动释放池中,并在每次将对象放入池中时收到释放消息。因此,发送自动释放而不是释放到对象会延长该对象的生命周期,至少直到池本身被释放为止(如果该对象在临时中保留,则该对象可以存活更长时间。)   ...
  Application Kit会在事件周期(或事件循环迭代)开始时自动创建一个池,例如鼠标按下事件,并在结束时释放它,因此您的代码通常不必担心它们。但是,有三种情况可以使用您自己的自动释放池:
  ...

因此,如果您需要在相应的自动释放池耗尽后让您的实例保持活动状态,请通过保留它们来获取所有权。否则你通常只是让他们在游泳池处理。

答案 1 :(得分:3)

  

由于我正在处理释放先前已分配的对象,因此没有内存泄漏,对吧?

  

“失去对它的引用”是什么意思?

您没有指向该对象,因此可能无法在您的程序中访问该对象。

  

仅关于apple的内存管理建议(调用者没有表明他们拥有返回的对象)这是错误的,或者这在技术上也是错误的?

也正确。静态分析仪也会大声哭泣

  

在我的函数调用后多远(或深)obj1返回的自动释放对象将可用。关于苹果的文档“自动释放对象将在其可变范围内可用”。我应该在某个时候保留它吗?

这有点复杂。自动释放池通过线程堆叠在一起。这就是为什么你必须在进入线程或新事件循环迭代时创建一个,以及为什么在执行创建许多(自动释放)分配的大型操作时显式创建它们的原因。

最后,在运行循环的迭代结束时,堆栈中的最后一个池(用于线程)被销毁。

如果对象是在您明确创建的自动释放池下创建的,那么您必须保留它以在其创建的池的生命周期之外使用它。

同样,您必须在传递给其他线程时正式保留/复制。通常,这会立即发生 - 您只需在输入辅助线程的实现时创建副本或保留正式参数。