views:

37

answers:

3

If thread A sends a reference to an object to thread B, for example using performSelector:onThread:withObject:waitUntilDone, how should memory management occur? Should the calling thread alloc the object and the called thread release it?

EDIT:

It turns out that performSelector:onThread:withObject:waitUntilDone retains the object until the selector, which will be called on the other thread's run loop, is done with it. So the calling thread should alloc, then call performSelector, then release.

+1  A: 

I'm not sure there is really a "correct" answer here. If the calling thread has exited or otherwise isn't able to track that the memory is no longer in use and release it, I guess you'd have to do it in the called thread. However, in general, I prefer to release the memory as in the same thread as it was allocated, ideally nearby in the code.

I think the key is clearly documenting what your expectations are and maintaining consistency.

easel
How to know in the calling+allocating thread when the called thread is done with the object, so that it is safe to release it?
apalopohapa
You'd have to have some sort of inter-thread signalling. Typically, you'd want to have that anyway...
easel
Releasing memory in the source thread may not be practical if the target thread is accessed in a "fire and forget" manner, say via some queue rather than direct signalling. We may not want or need the target thread to notify the source that each unit of work is complete.
Steve Townsend
+2  A: 

One option that may prevent excessive leaks or scribbling would be to pass around your memory wrapped in boost::shared_ptr. Provided of course you can guarantee the usage of the contents is thread-safe when multiple threads have a shared_ptr by which they can access it, this would ensure that leaving the scope of the final user of the memory in question would cause it to be released.

Steve Townsend
A: 

It turns out that performSelector:onThread:withObject:waitUntilDone retains the object until the selector, which will be called on the other thread's run loop, is done with it. So the calling thread should alloc, then call performSelector:onThread:withObject:waitUntilDone, then release.

apalopohapa