Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 目标-C返回alloc';函数中的d内存==坏?_Iphone_Objective C_Memory Management - Fatal编程技术网

Iphone 目标-C返回alloc';函数中的d内存==坏?

Iphone 目标-C返回alloc';函数中的d内存==坏?,iphone,objective-c,memory-management,Iphone,Objective C,Memory Management,这是在iPhone上 如果我有一个函数,比如 - (SomeObject*)buildObject; 我需要传入一个我已经分配好的变量吗 - (void)assignObject(SomeObject** out); 或者我能做什么 - (SomeObject*)buildObject { return [[[SomeObject alloc] init] autorelease]; } 像这样使用它 SomeObject* obj = [[otherObject buildObje

这是在iPhone上

如果我有一个函数,比如

- (SomeObject*)buildObject;
我需要传入一个我已经分配好的变量吗

- (void)assignObject(SomeObject** out);
或者我能做什么

- (SomeObject*)buildObject
{
   return [[[SomeObject alloc] init] autorelease];
}
像这样使用它

SomeObject* obj = [[otherObject buildObject] retain];

我想做最后一个,但据我所知,这是未定义的,因为自动释放只保证对象在函数结束之前是安全的?

使用最后一个是安全的。我在我的每一个应用程序中都使用这种风格,从来没有出现过问题。自动释放将持续很多很多执行周期,比函数结束时长得多。

在Objective-C中,内存管理契约如下:调用alloc的人负责调用release。如果构造函数调用[[[Class alloc]init]release],那么对象将被快速创建和销毁

要解决此问题,构造函数需要使用autorelease,如下所示:

return [[[Class alloc] init] autorelease];
在当前运行循环结束时注册要释放的对象,除非有东西保留它,例如构造函数的调用方。在你的例子中,第二个例子正是你想要做的

因此:


Autorelease保证对象在当前NSAutoreleasePool的释放/释放之前一直处于活动状态


从一个方法返回一个自动删除的对象是完全可以接受的(也是标准的做法)。

关于如何在Cocoa中这样做,有一种解决方案;阅读文档了解详细信息

基本上,如果您有一个以initnewcopy开头的方法,则返回一个保留的对象,并且必须释放它。
如果提供方便的方法,则返回一个自动删除的对象

这意味着:

- (id) initMyObject
{
    self = [super init];
    if (self) {
        // do something
    }
    return self
}
➔ 必须释放使用此方法获得的对象

- (MyObject *) myObject
{
    return [[[MyObject alloc] initMyObject] autorelease];
}

➔ 这是一种方便的方法-对象由该方法自动释放,如果您希望保留该对象的时间长于自动释放池清空之前(您应该假设该时间发生在当前方法结束时)。

您可以做您想做的事。在释放当前自动释放池之前,自动释放不会向对象发出释放消息。发生这种情况的原因可能是您显式地请求了它(通过allocing+初始化NSAutoreleasePool,然后将其排空),也可能是因为系统这样做了。系统自动释放池的创建和排放发生在事件周期的开始和结束时;从内存管理编程指南:

应用程序包将自动关闭 在项目的开头创建一个池 事件循环(或事件循环迭代), 例如鼠标按下事件,以及 在最后释放它,因此您的代码 平时不用担心 他们


实际上,这意味着您想做的事情是安全的,因为您编写的所有代码都将在一个事件周期内一起执行。

因此,如果我不想在doSomething之外使用它,我不必立即调用retain?是的,您可以。该对象(如果是自动释放的对象)保证在当前方法结束之前保留在内存中,但不会更长。它可能会活得更长,但你不能依赖它(当然,假设你没有自己的自动释放池),所以你不同意布莱恩·桑霍洛的观点?如果doSomething做了一些长时间的计算,那么c不能保证在函数结束时出现?不,布莱恩是正确的,我并不反对他在整个剂量测定法中,c一定存在,但当该方法结束时,池可能会被清理,c会消失。如果您从doSomething中调用另一个方法,那么c仍然存在,因为doSomething尚未结束。只是一个旁注,objective-c命名约定建议您将buildObject便利方法命名为“object”,与NSArray使用便利方法[NSArray array]的方式大致相同它返回一个自动释放数组。此外,它应该是一个类方法(+),而不是一个实例方法(-),除非出于其他原因需要。自动释放保证对象在当前自动释放池释放之前一直存在。不,它不存在。自动释放只是一种延迟消息机制。这不能保证什么,说得好,我说错了。Autorelease将保持其对对象的引用计数句柄,直到当前Autorelease池被释放。此外,Clang静态分析器的一个优点是,如果在将对象保留或自动释放为返回值时没有正确遵循方法的命名约定,它将警告您。这是一个伟大的精神检查。
- (MyObject *) myObject
{
    return [[[MyObject alloc] initMyObject] autorelease];
}