Reputation: 1
I am initializing an NSArray using a C array of objects I dynamically create:
MyClass *initArray [dynamicSize];
for (NSUInteger i=0; i<dynamicSize; i++) {
initArray [i] = [[MyClass alloc] initWithSomthingDependingOn: i];
}
// At this point, initArray contains objects with retainCount == 1
classObjectArray = [[NSArray alloc] initWithObjects:initArray count:dynamicSize];
// And... at this point, retainCount == 2
My problem/doubt is about how to deal with memory management in this situation. My understanding is that I should be releasing all the objects once to keep retainCount == 1, for I will only keep one reference to them (initArray will disappear after the function returns)... but I find it inefficient having to iterate again through the array just to do this.
Any suggestions?
Thanks in advance
Edit: to avoid confusing code example modified swapping initExpresion (i)
to [[MyClass alloc] initWith... ]
which better represents the nature of the problem.
Upvotes: 0
Views: 162
Reputation: 162712
Any suggestions?
Yes.
It is misleading at best and flat out useless most of the time.
As Jonathan said, only balance retains that you cause via the various methods listed. That is, treat the retain count like a delta. If you increase it, you must decrease it.
In this specific case, the "initExpression()
" is either returning a retained or autoreleased object. You can't tell via retainCount
since autorelease
doesn't immediately decrement that count (it is, effectively, a delayed release
).
(No, initExpression()
didn't confuse the question or this answer -- retainCount
is useless for "detecting" an autoreleased object.)
In a comment, you said:
I am concerned about the performance impact of either autoreleasing the objects or iterating again through the array to send a release message to all of the objects.
Concerned because you measured a problem or because it seems like it might be an issue?
Don't waste time fixing performance problems that haven't been quantified. It is exceedingly unlikely that the objects being either manually released or autoreleased is going to be a problem in that context. It can happen, but not unless you have Ns of thousands of objects (at which point you might have a memory issue in and of itself) or are calling through this code many times.
Jonathan's suggestion of skipping the C array entirely is a good one!
Upvotes: 1
Reputation: 43472
initExpression()
should be autoreleasing its resultant objects since its name does not begin with retain
, create
, new
, copy
, or alloc
. If it does, the problem goes away.
If the objects it returns are not autoreleased, then it is the caller's (your) responsibility to either releas
or autorelease
those objects after using them.
Edit: Of course, you could just skip the C array and use an NSMutableArray
with a capacity of dynamicSize
:
NSMutableArray *classObjectArray = [NSMutableArray arrayWithCapacity: dynamicSize];
for (NSUInteger i = 0; i < dynamicSize; i++) {
id myObject = [[MyClass alloc] init...];
if (myObject) {
[classObjectArray addObject: myObject];
[myObject release];
}
}
Upvotes: 0