Question

I have a method of an object which creates objects which are then passed to a method of another object in another thread, like this:

MyClass* myClass = [[MyClass alloc] init];
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];

in method, I immediately retain the object, supposing it will be somehow released by the creator. My question is: how do I make MyClass release that object correctly? Is this the correct way to go?

My solution was to release the object manually in method. I see anyway that the Leak analyzer still recognizes this as a leak and seems it is not what Apple recommends, as the owner has the responsability to release the object.

Can you explain me the correct way to handle this situation? Thanks!

Was it helpful?

Solution

I don't fully understand what you're trying to achieve, but in general:

You shouldn't worry about who and when releases/deallocates the object. Instead, just make sure to retain it when you (a single object or method of yours) start needing it and release it when you stop needing it (or autorelease it, in which case it will be released on the thread on which you called autorelease).

This is exactly the way the performSelectorOnMainThread:withObject:waitUntilDone: works. From the documentation:

This method retains the receiver and the arg parameter until after the selector is performed.

It retains them while it needs them for doing it's job.

In short, the mehod that creates the objects and sends them to another thread should be:

MyClass* myClass = [[MyClass alloc] init]; // retained, will need it for performSelector
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];
[myClass release]; // no longer needing it.

or

MyClass* myClass = [[[MyClass alloc] init] autorelease]; // will be released automatically, but guaranteed to be retained until this method returns
[anotherClass performSelectorOnMainThread:@selector(method) withObject:myClass waitUntilDone:NO];

The way you have it now is a memory leak.

The receiving method:

  • if it uses the object only internally, doesn't have to retain it, since performSelector does "until after it is performed" (the method returns).
  • if it needs it later, it should be assigned to a property which retains it.

OTHER TIPS

Your question is very hard to understand because you talk about this object, that object, another object and use meaningless names like myClass, anotherClass and method. It remains unclear which object you intend to release and which one is reported as leaking.

Anyhow, multi-threading doesn't add any special complexity to reference counting. Certainly, your two object myClass and anotherClass aren't short-lived objects. So if you use autorelease, make sure that the reference counter doesn't go to 0 if all autoreleases have been executed.

It's perfectly okay to release either myClass or anotherClass or both in method.

You don't show a lot of code. But what you show is okay.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top