Re: makeing a copy of an object...
Re: makeing a copy of an object...
- Subject: Re: makeing a copy of an object...
- From: Shawn Erickson <email@hidden>
- Date: Tue, 01 Nov 2005 23:41:26 -0800
On Nov 1, 2005, at 5:31 PM, Brian O'Brien wrote:
I realize this may be a reiteration of my previously stated problem.
I would stick with just one list, likely Cocoa-dev for this question.
I have a thread and it creates object and stores them in an
NSMutableArray.
The thread creates these objects between a:
for (;;)
{
NSAutorelease *pool = [[NSAutoreleasePool alloc] init];
... create lots and lots of autoreleased objects and store them
in my NSMutableArray
the objects are then passed off to a different thread..
I assume you mean that the NSMutableArray is passed off to another
thread?
[pool release];
}
As the main application doesn't know when the thread is going to
release the objects and thread doesn't know when the main application
is going to release the objects,
The Cocoa memory contract/paradigm is intended to help avoiding to
have to worry about such things (I pointed out docs that discuss the
contract in prior emails, but just in case this sums it up [1]). All
you should need to do is follow the contract consitently and if
needed use critical sections to protect against aspects that cannot
tolerate concurrency (often for things unrelated to memory management).
In your code above you are filling a mutable array with objects that
sound to have the only "active" retain coming from the mutable array
itself (objects are retained when added to an array). If other code/
threads want to have access to an object they should retain the
object for as long as they need it then release/autorelease it when
they don't need it. They really shouldn't have to care about who else
may have retained it.
[1] <http://developer.apple.com/documentation/Cocoa/Conceptual/
MemoryMgmt/Tasks/MemoryManagementRules.html>
I think it would be best if the main thread
made copies of the objects of the thread and let the thread go on
as if
there were no main application.....
It may make sense to copy/mutableCopy objects that are mutable so
that a second thread (etc.) cannot modify an object in a way that you
don't expect. If an object is immutable or otherwise expected not to
modified then often a simple retain is sufficient to insure continued
existence of a need object (in fact many immutable objects implement
copy using a simple retain).
- (id) getNextImage
{
id x;
x = [dataSets objectAtIndex:0];
[dataSets removeObjectAtIndex:0];
return x;
}
This is code in the thread that the main application calls to get
an instance of
one of the objects that the thread creates.
I assume that the main application should do:
id * myimage = [[sender getNextImage] copy];
So does this look right?
No :)
Going on the code snippets you have outlined so far doing "[[sender
getNextImage] copy]" wont work since your getNextImage method removes
the object it wants to return the caller from the array that was
containing it. When removed from the array the object is sent a
release. If the only active retain on that object is coming from the
array itself (as you imply above) then the object will be deallocated
as a result of the removeObjectAtIndex message. So the caller of
getNextImage will get a pointer to a now deallocated object, sending
it a copy message wont fix that.
As others have suggested you will need to modify your getNextImage
method to ensure that a caller will at least get a chance to send a
message to the object they are asking for (possibly to retain it for
their own use). To do that you would likely leverage autorelease
so... replace "x = [dataSets objectAtIndex:0];" with "x = [[[dataSets
objectAtIndex:0] retain] autorelease];" in your getNextImage method.
What this does is retain the object you fetch from index 0 of the
array, adds that object to the current autorelease pool and all
before you remove the object from the array that contained it. The
retain you send will insure the object will continue to exist after
you remove the object from the array and the autorelease will balance
that retain with a release at a future date (when the current
autorelease pool itself is deallocated).
This will give the caller of getNextImage a chance to message the
object in question.
Does this mean that the class of object needs to implement a copy
or copyWithZone method?
If you want to use copy (in the traditional sense) then your object
would need to adhere to the NSCopying protocol.
<http://developer.apple.com/documentation/Cocoa/Conceptual/MemoryMgmt/
Tasks/ImplementCopy.html>
Any help and corrections are appreciated...
Hate to bring this up again and again but I think memory management
in Cocoa still hasn't clicked for ya.
-Shawn
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden