Objective-C返回一个函数中的alloc内存=坏?

时间:2022-09-07 11:21:00

This is on the iPhone.

这是在iPhone上。

So what if I have a function like

如果我有一个函数

- (SomeObject*)buildObject;

Do I need to pass in a variable that I have already alloc'd outside like

我是否需要传递一个我已经在外面分配的变量

- (void)assignObject(SomeObject** out);

Or can I do

或者我能做

- (SomeObject*)buildObject
{
   return [[[SomeObject alloc] init] autorelease];
}

and use it like

和使用它

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

I would like to do the last one, but as far as I've read this is undefined because autorelease only guarantees the object until the end of the function?

我想做最后一个,但是就我所读到的而言,这是没有定义的,因为autorelease只保证对象直到函数结束?

5 个解决方案

#1


6  

In Objective-C, the memory management contract goes as follows: whoever calls alloc is responsible for calling release. If the constructing function calls [[[Class alloc] init] release] then the object is quickly created and destroyed.

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

To get around this, the constructing function would need to use autorelease as follows:

为了解决这个问题,构造函数需要使用如下的自动发送:

return [[[Class alloc] init] autorelease];

That registers the object to be released at the end of the current run loop unless something retains it, such as the caller of the constructing function. In your case, the second example is exactly what you want to do.

在当前运行循环的末尾注册要释放的对象,除非某些东西保留了它,例如构造函数的调用者。在你的例子中,第二个例子就是你想要做的。

So:

所以:

- (SomeClass*) buildObject {
   return [[[SomeClass alloc] init] autorelease];
}

- (void) doSomething {
   c = [self buildObject];
   // Call [c retain] if you want c to stay around after the current run
   // loop is finished and clean it up later, e.g. in your delloc method.
}

#2


4  

There is kind of a settlement on how you should do this in Cocoa; read the docs for details.

关于如何用可可做这个有一个解决方案;详细阅读文档。

Basically, if you have a method that starts with init, new or copy, you return an object that is retained and you must release it.
If you provide a convenience method, you return an object that is autoreleased.

基本上,如果你有一个以init, new或copy开头的方法,你返回一个被保留的对象,你必须释放它。如果您提供了一个方便的方法,您将返回一个自动加载的对象。

This means:

这意味着:

- (id) initMyObject
{
    self = [super init];
    if (self) {
        // do something
    }
    return self
}

➔ You must release objects obtained with this method

➔你必须释放对象用这种方法获得的

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

➔ This is a convenience method - the object is autoreleased by the method and you must retain it if you want to keep it longer than until the autorelease pool empties (which you should assume happens at the end of the current method).

➔这是一个方便的方法——对象生成的方法和你必须保留它,如果你想让它超过直到autorelease池清空(你应该假设发生在当前的方法)。

#3


1  

Autorelease guarantees the object until the release/drain of the current NSAutoreleasePool.

Autorelease保证对象直到当前的NSAutoreleasePool释放/耗尽。

It's perfectly acceptable (and standard practice) to return an autoreleased object from a method.

从方法返回一个autoreleated对象是完全可以接受的(也是标准的实践)。

#4


1  

You can do what you want to do. Autorelease doesn't issue a release message to the object until the current autorelease pool is freed. That happens either because you explicitly requested it (by allocing+initing an NSAutoreleasePool and later draining it), or because the system did so. The system autorelease pool creation and draining happens at the beginning and end of event cycles; from the memory management programming guide:

你可以做你想做的事。在释放当前的Autorelease池之前,Autorelease不会向对象发出发布消息。这可能是因为您显式地请求了它(通过allocing+输入一个NSAutoreleasePool并随后将其耗尽),或者因为系统这样做了。系统自动释放池的创建和排水发生在事件周期的开始和结束;内存管理编程指南:

The Application Kit automatically creates a pool at the beginning of an event cycle (or event-loop iteration), such as a mouse down event, and releases it at the end, so your code normally does not have to worry about them.

应用程序工具包在事件周期(或事件循环迭代)的开始自动创建一个池,例如鼠标向下事件,并在结束时释放它,因此您的代码通常不必担心它们。

In practice, that means that what you want to do is safe, as all the code you write will get executed together within a single event cycle.

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

#5


0  

You are safe using the last one. I use this style in every one of my apps and have never had issues. Autorelease will last for many, many, many execution cycles, much longer than the end of the function.

使用最后一个是安全的。我在我的每一个应用中都使用这种风格,从来没有遇到过问题。Autorelease将会持续许多,许多,许多执行周期,比函数的结束时间更长。

#1


6  

In Objective-C, the memory management contract goes as follows: whoever calls alloc is responsible for calling release. If the constructing function calls [[[Class alloc] init] release] then the object is quickly created and destroyed.

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

To get around this, the constructing function would need to use autorelease as follows:

为了解决这个问题,构造函数需要使用如下的自动发送:

return [[[Class alloc] init] autorelease];

That registers the object to be released at the end of the current run loop unless something retains it, such as the caller of the constructing function. In your case, the second example is exactly what you want to do.

在当前运行循环的末尾注册要释放的对象,除非某些东西保留了它,例如构造函数的调用者。在你的例子中,第二个例子就是你想要做的。

So:

所以:

- (SomeClass*) buildObject {
   return [[[SomeClass alloc] init] autorelease];
}

- (void) doSomething {
   c = [self buildObject];
   // Call [c retain] if you want c to stay around after the current run
   // loop is finished and clean it up later, e.g. in your delloc method.
}

#2


4  

There is kind of a settlement on how you should do this in Cocoa; read the docs for details.

关于如何用可可做这个有一个解决方案;详细阅读文档。

Basically, if you have a method that starts with init, new or copy, you return an object that is retained and you must release it.
If you provide a convenience method, you return an object that is autoreleased.

基本上,如果你有一个以init, new或copy开头的方法,你返回一个被保留的对象,你必须释放它。如果您提供了一个方便的方法,您将返回一个自动加载的对象。

This means:

这意味着:

- (id) initMyObject
{
    self = [super init];
    if (self) {
        // do something
    }
    return self
}

➔ You must release objects obtained with this method

➔你必须释放对象用这种方法获得的

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

➔ This is a convenience method - the object is autoreleased by the method and you must retain it if you want to keep it longer than until the autorelease pool empties (which you should assume happens at the end of the current method).

➔这是一个方便的方法——对象生成的方法和你必须保留它,如果你想让它超过直到autorelease池清空(你应该假设发生在当前的方法)。

#3


1  

Autorelease guarantees the object until the release/drain of the current NSAutoreleasePool.

Autorelease保证对象直到当前的NSAutoreleasePool释放/耗尽。

It's perfectly acceptable (and standard practice) to return an autoreleased object from a method.

从方法返回一个autoreleated对象是完全可以接受的(也是标准的实践)。

#4


1  

You can do what you want to do. Autorelease doesn't issue a release message to the object until the current autorelease pool is freed. That happens either because you explicitly requested it (by allocing+initing an NSAutoreleasePool and later draining it), or because the system did so. The system autorelease pool creation and draining happens at the beginning and end of event cycles; from the memory management programming guide:

你可以做你想做的事。在释放当前的Autorelease池之前,Autorelease不会向对象发出发布消息。这可能是因为您显式地请求了它(通过allocing+输入一个NSAutoreleasePool并随后将其耗尽),或者因为系统这样做了。系统自动释放池的创建和排水发生在事件周期的开始和结束;内存管理编程指南:

The Application Kit automatically creates a pool at the beginning of an event cycle (or event-loop iteration), such as a mouse down event, and releases it at the end, so your code normally does not have to worry about them.

应用程序工具包在事件周期(或事件循环迭代)的开始自动创建一个池,例如鼠标向下事件,并在结束时释放它,因此您的代码通常不必担心它们。

In practice, that means that what you want to do is safe, as all the code you write will get executed together within a single event cycle.

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

#5


0  

You are safe using the last one. I use this style in every one of my apps and have never had issues. Autorelease will last for many, many, many execution cycles, much longer than the end of the function.

使用最后一个是安全的。我在我的每一个应用中都使用这种风格,从来没有遇到过问题。Autorelease将会持续许多,许多,许多执行周期,比函数的结束时间更长。