PDA

View Full Version : Dealloc With Fast Enumeration?




Darkroom
Jul 10, 2009, 10:28 PM
in my awakeFromNib method i have added most of my NIB objects into mutable arrays so i can call them in my code. is it ok to release those objects using fast enumeration in the dealloc method?


- (void)dealloc
{
for (id objects in array1)
[objects release];

[array1 release];

for (id objects in array2)
[objects release];

[array2 release];
[super dealloc];
}



kpua
Jul 10, 2009, 10:56 PM
Why would you need to? Why not let the array just hold onto the last reference, so that by releasing the array, you release all the objects?

larkost
Jul 11, 2009, 12:02 AM
You can't change the object you are iterating over in fast enumeration.

Darkroom
Jul 11, 2009, 12:09 AM
i'm setting properties for all of the objects, including the array objects. so even if i add those objects to an array in the init method, don't i still have to release each object, and not just the array that holds them?

but anyway, i've realized that since they are mutable arrays, the contents of the arrays with be changing through out the program, so i'll just have to release each one individually in dealloc to make sure they all get released.

kpua
Jul 11, 2009, 01:59 AM
I see. Honestly, I'm curious why you're putting them in an array in the first place. It seems redundant. Why not just have them as ivars if you've already got @properties for them?

Furthermore, it is indeed OK to -release objects in an array in fast enumeration. You can even modify their contents. The only restriction is that you don't modify the array structure itself—no addObject:, removeObject: calls that modify the pointers that the array contains or the size of the array.

(NOTE: The same does not hold true of sets or keys in dictionaries. Once those objects get put into the collection, you should not modify them at all, because you might change the hash value, causing the collection to lose track of the objects.)

Darkroom
Jul 11, 2009, 02:07 AM
thanks.

the reason i'm throwing objects into arrays is because i'm sometimes animating most of them with the same movements, except for one or two, which i remove from the array before animation. it's code refactoring. instead of listing 20 variables within several animation methods, removing an object or two before calling animations on one NSMutableArray using fast enumeration is easier to maintain.

autorelease
Jul 11, 2009, 04:36 PM
thanks.

the reason i'm throwing objects into arrays is because i'm sometimes animating most of them with the same movements, except for one or two, which i remove from the array before animation. it's code refactoring. instead of listing 20 variables within several animation methods, removing an object or two before calling animations on one NSMutableArray using fast enumeration is easier to maintain.

Shouldn't you be using inheritance, so each class knows how to perform its movements? Removing items from an array before performing an operation on the entire array is inefficient and kinda defeats the purpose of using an object-oriented language...

Also, collection classes retain objects added to them and release them on dealloc. If the objects you put into an array are autoreleased after creation (or created with factory methods) then you don't have to worry about releasing the individual members of the array.

Darkroom
Jul 11, 2009, 07:56 PM
Shouldn't you be using inheritance, so each class knows how to perform its movements? Removing items from an array before performing an operation on the entire array is inefficient and kinda defeats the purpose of using an object-oriented language...

not sure i follow you. i'm adding objects like UIButtons, UIImageViews and Labels to the array. if a certain button is clicked (or tapped since it's on iPhone), that button is removed from the array and enlarged, while all the other objects within the array are animated off screen. but if a different button was tapped, the first button would remain in the array so it too would be animated off screen. which ever button is tapped, it will execute a different animation than all the other objects in the array. all these buttons, views and labels are members of an elite squad known as the special victims unit *record scratch* sorry... they're all members of a view controller class, so i'm not sure what you mean by suggesting the use of inheritance in animating select objects.

autorelease
Jul 12, 2009, 12:26 AM
not sure i follow you. i'm adding objects like UIButtons, UIImageViews and Labels to the array. if a certain button is clicked (or tapped since it's on iPhone), that button is removed from the array and enlarged, while all the other objects within the array are animated off screen. but if a different button was tapped, the first button would remain in the array so it too would be animated off screen. which ever button is tapped, it will execute a different animation than all the other objects in the array. all these buttons, views and labels are members of an elite squad known as the special victims unit *record scratch* sorry... they're all members of a view controller class, so i'm not sure what you mean by suggesting the use of inheritance in animating select objects.

Okay, I see what you mean. I couldn't really tell what you were trying to accomplish from your previous post.

You should probably keep one array for all objects, and create another one just for the objects you want to animate. Put the objects you want to animate into this second array before you start the animation, and empty it when the animation is finished.

lee1210
Jul 12, 2009, 12:45 AM
Okay, I see what you mean. I couldn't really tell what you were trying to accomplish from your previous post.

You should probably keep one array for all objects, and create another one just for the objects you want to animate. Put the objects you want to animate into this second array before you start the animation, and empty it when the animation is finished.

Or keep one array, period:

theOne = clickedThing;
for(id myThing in myControls) {
if(myThing == theOne) continue;
[myThing animate];
}


-Lee

jared_kipe
Jul 13, 2009, 07:34 AM
Since you are simply sending a message to every object, why not just us NSArray's instance method:
- (void)makeObjectsPerformSelector:(SEL)aSelector

Meaning something like..
[myArray makeObjectsPerformSelector: @selector(release) ];

I would think this is as fast or faster.

Littleodie914
Jul 13, 2009, 01:24 PM
Maybe I misunderstood your question, but why not just release the objects once they are placed into the array in the beginning? Eg:


- (void)awakeFromNib {
NSMutableArray arrayOfThings = [[NSMutableArray alloc] init];
[arrayOfThings addObject:tableView];
[tableView release];
[arrayOfThings addObject:textField];
[textField release];
}


When you call 'release' on an array, it also sends release to all of its contained elements. So if the retain count of any of the objects in your array is '1', they will be automatically released with the array. Eg:



- (void)dealloc {
[arrayOfThings release]; // Release is also sent to all elements
[super release];
}