English 中文(简体)
Objective-C returning alloc d memory in a function == bad?
原标题:

This is on the 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?

最佳回答

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.

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.
}
问题回答

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.

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 guarantees the object until the release/drain of the current NSAutoreleasePool.

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

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:

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.

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.





相关问题
Code sign Error

I have created a new iPhone application.I have two mach machines. I have created the certificate for running application in iPhone in one mac. Can I use the other mac for running the application in ...

ABPersonViewController Usage for displaying contact

Created a View based Project and added a contact to the AddressBook using ABAddressBookRef,ABRecordRef now i wanted to display the added contact ABPersonViewController is the method but how to use in ...

将音频Clips从Peter改为服务器

我不禁要问,那里是否有任何实例表明从Peit向服务器发送音响。 I m不关心电话或SIP风格的解决办法,只是一个简单的袖珍流程......

• 如何将搜查线重新定位?

我正试图把图像放在搜索条左边。 但是,问题始于这里,搜索条线不能重新布署。

热门标签