Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Mockup & CodeGen, iPhone & iPad
($9.99)

Make your own iPhone apps
and run them live!
(free)

Manu
($0.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 04-23-2009, 02:33 AM   #1 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 20
Question NSMutableArray release Problem

Hello Guys,

I am stuck in crashes. I m doing following thing in a function

NSMutableArray *myMutableArray=[[NSMutableArray alloc] initWithCapacity:0]];

for (int i=0;i<10;i++)
[myMutableArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d.png",(start+i+1)] ofType:nil]]];

self.myImageView.animationImages=myMutableArray;

[myMutableArray removeAllObjects];

//[myMutableArray release];

I have around 50 images and I load only 10 at a time for a purpose, I am controlling this my "start" variable which contains the initial point. And I want to free previous loaded images while loading new ones.

But when I uncomment the release method My program crashes..
And if I do not release My memory is not being freed, as I checked in Instruments, although there is not leak in Leaks but still object allocation goes on and on with overall system memory of 100 MB. And because of this I get Low Memory Warning in program when I test in the device. I don't know what is the problem here. Please let me know if anyone has resolution.

Thanks in advance.

Regards,
Sanniv.
sanniv is offline   Reply With Quote
Old 04-23-2009, 03:28 AM   #2 (permalink)
Registered Member
 
Join Date: Mar 2009
Posts: 246
Default

ok... i really dont know if this is right, but it may be worth checking...

you have to set the array to nil before you try and release it dont you? is removeAllObjects the same as setting to nil?
gabacus is offline   Reply With Quote
Old 04-23-2009, 04:08 AM   #3 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 20
Default

Quote:
Originally Posted by gabacus View Post
ok... i really dont know if this is right, but it may be worth checking...

you have to set the array to nil before you try and release it dont you? is removeAllObjects the same as setting to nil?
------------------------

You mean to say instead of
[myMutableArray release];
I should do
myMutableArray=nil;
But this will just put the nil value at myMutableArray pointer without freeing the memory, I guess..


The removeAllObjects method removes all the objects present in the array as per the Apple documentation. It doesn't release the array, I guess.
sanniv is offline   Reply With Quote
Old 04-23-2009, 06:52 AM   #4 (permalink)
Candy Mountain, Charlie..
 
ovidiu's Avatar
 
Join Date: Mar 2009
Location: Romania
Age: 25
Posts: 116
Default

I have a suggestions, but I'm not giving any warranties:

Code:
NSMutableArray *myMutableArray=[[NSMutableArray alloc] init];

for (int i=0;i<10;i++)
[myMutableArray addObject:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d.png",(start+i+1)] ofType:nil]]];

self.myImageView.animationImages=myMutableArray;

[myMutableArray autorelease];
Try to use autorelease for a local object with alloc/init method.
ovidiu is offline   Reply With Quote
Old 04-23-2009, 08:22 AM   #5 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 20
Default

No luck with AutoRelease also
sanniv is offline   Reply With Quote
Old 04-23-2009, 08:47 AM   #6 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
Default

The program is probably crashing because your myImageView class is trying to use the image array you just released. Let's see the code for it.

joe
FlyingDiver is offline   Reply With Quote
Old 04-23-2009, 09:28 AM   #7 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

These two lines are interesting:

Code:
self.myImageView.animationImages=myMutableArray;

[myMutableArray removeAllObjects];
I assume animationImages is a property with a "copy" attribute? Otherwise, why would you be setting it and then immediately emptying the array?

If it's a retain, then your imageView now has an empty array in "animationImages", which is most likely not what you wanted.

Also, where exactly is the program crashing? What exception are you getting?
eddietr is offline   Reply With Quote
Old 04-23-2009, 10:31 AM   #8 (permalink)
Registered Member
 
Join Date: Aug 2008
Location: Memphis, TN, USA
Age: 24
Posts: 3,558
Send a message via ICQ to smithdale87 Send a message via AIM to smithdale87 Send a message via Skype™ to smithdale87
Default

another thing i see thats incorrect is
Code:
[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d.png",(start+i+1)] ofType:nil]
;

it should be
Code:
[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d",(start+i+1)] ofType:@"png"];
smithdale87 is offline   Reply With Quote
Old 04-23-2009, 01:45 PM   #9 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 20
Default

actually "animationImages" is the copy property of UIImageView and myImageView is the reference of UIImageView, so all the date in myMutableArray will get copied to it when i assign. Hence I want to free the data of myMutableArray because there will be 2 copies of same data in the memory... right?
Quote:
Originally Posted by FlyingDiver View Post
The program is probably crashing because your myImageView class is trying to use the image array you just released. Let's see the code for it.

joe
sanniv is offline   Reply With Quote
Old 04-23-2009, 01:46 PM   #10 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 20
Default

Quote:
Originally Posted by smithdale87 View Post
another thing i see thats incorrect is
Code:
[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d.png",(start+i+1)] ofType:nil]
;

it should be
Code:
[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d",(start+i+1)] ofType:@"png"];

Well, it is loading perfectly and being displayed on the screen successfully with the first option....
sanniv is offline   Reply With Quote
Old 04-23-2009, 01:50 PM   #11 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 20
Default

Quote:
Originally Posted by eddietr View Post
These two lines are interesting:

Code:
self.myImageView.animationImages=myMutableArray;

[myMutableArray removeAllObjects];
I assume animationImages is a property with a "copy" attribute? Otherwise, why would you be setting it and then immediately emptying the array?

If it's a retain, then your imageView now has an empty array in "animationImages", which is most likely not what you wanted.

Also, where exactly is the program crashing? What exception are you getting?
yess the "animationImages" is the copy property of UIImageView of which the reference is "myImageView". Program crashes when I uncomment release method without giving any exception, but when I trace in debug mode I got to know that NSAutoReleasePool fails...
but when I comment the release method then program works fine but i get low memory warning call back..
sanniv is offline   Reply With Quote
Old 04-23-2009, 02:31 PM   #12 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by smithdale87 View Post
another thing i see thats incorrect is
Code:
[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d.png",(start+i+1)] ofType:nil]
;

it should be
Code:
[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"img000%d",(start+i+1)] ofType:@"png"];
Those are both basically the same thing. Either works.
eddietr is offline   Reply With Quote
Old 04-23-2009, 02:39 PM   #13 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 812
Default

Quote:
Originally Posted by sanniv View Post
yess the "animationImages" is the copy property of UIImageView of which the reference is "myImageView". Program crashes when I uncomment release method without giving any exception, but when I trace in debug mode I got to know that NSAutoReleasePool fails...
but when I comment the release method then program works fine but i get low memory warning call back..
why copy attribute?

I bet if you comment out
self.myImageView.animationImages=myMutableArray;

It won't crash.
johnqh is offline   Reply With Quote
Old 04-23-2009, 02:44 PM   #14 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 812
Default

A little more explanation.

Your "copy" property of NSMutableArray won't add reference count to the objects in the array.

Those UIImage are created with autorelease. Their reference count +1 when you add them to the array, but when you removeAllObjects (or the array release), their reference count -1. And then, at the end of autorelease pool, they are dealloc'd.

Which means your animationImages array contains pointers which are invalid.
johnqh is offline   Reply With Quote
Old 04-23-2009, 03:09 PM   #15 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by johnqh View Post
Your "copy" property of NSMutableArray won't add reference count to the objects in the array.
Actually, it does add to the reference count. It's a shallow copy, but retains are sent to the objects.

Quote:
Their reference count +1 when you add them to the array, but when you removeAllObjects (or the array release), their reference count -1. And then, at the end of autorelease pool, they are dealloc'd.
But then he should get the same behavior regardless of whether he removes all objects or releases the array. But he says he is not getting the same behavior.

Sanniv, can you show us the header file for the class of myImageView? (and please use code tags)
eddietr is offline   Reply With Quote
Old 04-24-2009, 02:27 AM   #16 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 20
Default

UIImageView *myImageView;
Quote:
Originally Posted by eddietr View Post
Actually, it does add to the reference count. It's a shallow copy, but retains are sent to the objects.



But then he should get the same behavior regardless of whether he removes all objects or releases the array. But he says he is not getting the same behavior.

Sanniv, can you show us the header file for the class of myImageView? (and please use code tags)
sanniv is offline   Reply With Quote
Old 04-24-2009, 07:31 AM   #17 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
Default

Quote:
Originally Posted by sanniv View Post
UIImageView *myImageView;
If myImageView is just a pointer to an UIImageView, where is animationImages defined? I think everyone is assuming is an instance variable of your custom class, but that might not be the case. If myImageView is not a custom class, then what does this mean?

Quote:
yess the "animationImages" is the copy property of UIImageView of which the reference is "myImageView".
joe
FlyingDiver is offline   Reply With Quote
Old 04-24-2009, 08:50 AM   #18 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by sanniv View Post
UIImageView *myImageView;
Ah, OK, I was thinking that was your own class. So you're just using a regular UIImageView.

Ok, so then I don't see the problem. Memory management bugs are tricky, because ultimately you need to have a balance between retains and releases, right. So if you have too many releases (which it sounds like is the issue here), then removing any one of the releases will mask the problem, but not solve it.

So I think the issue is somewhere else in your code. My guess is the images themselves are being released somewhere else where they shouldn't be.
eddietr is offline   Reply With Quote
Old 04-24-2009, 08:52 AM   #19 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by FlyingDiver View Post
If myImageView is just a pointer to an UIImageView, where is animationImages defined?
It's a property of UIImageView. I thought he had a custom class and that he was somehow inadvertently masking that property, which is why I asked for the header file. But that's not the issue, he's just using a regular old UIImageView.
eddietr is offline   Reply With Quote
Old 04-24-2009, 02:47 PM   #20 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 3,858
Default

Quote:
Originally Posted by eddietr View Post
It's a property of UIImageView. I thought he had a custom class and that he was somehow inadvertently masking that property, which is why I asked for the header file. But that's not the issue, he's just using a regular old UIImageView.
(1) If animationImages makes a copy of the array, it doesn't matter what you do to the old array. If animationImages just retains the old array, then you shouldn't remove all of the images.

Either way, don't do
[myMutableArray removeAllObjects]
just do
[myMutableArray release]

If this is truly the LAST RELEASE, then the dealloc method will call removeAllObjects anyway.

(2) Are you sure the images are really getting loaded? You may want to add a breakpoint after the array gets filled up, and see if it really has items in it. There are lots of ways that this could go wrong:

stringWithFormat:@"img000%d.png",(start+i+1)

For example, you're taking "i" from zero to nine, but then you're adding one. And is "start" zero, or something else? If start is "200" (for example) then you're asking for images:

img000201.png
img000202.png
img000203.png
...
img000209.png
img000210.png

Are those the real image names?
__________________

Free Games!
smasher is offline   Reply With Quote
Old 04-24-2009, 03:02 PM   #21 (permalink)
Registered Member
 
Join Date: Feb 2009
Posts: 97
Default

i'm also having difficulty grasping how mutable arrays should be released.
what's the proper method to release your mutable arrays??

assume the array is created as follows (just rough code here).
Code:
-(void) viewDidLoad
{
 NSMutableArrray* mutable_array=[NSMutableArrray alloc] initWithCapacity:0];
 for (loop)
 {
      blah* object=[blah alloc] init];
      ... set some stuff in object ...
      [mutable_array addObject: object];
      [object release];
 }
// are the next two lines ok to do ? wrt reference counts, etc.
self.myMutable= mutable_array;  
[mutable_array release];

}

-(void) dealloc
{
    [self.myMutable release];  
}
is that right? or should i loop through self.myMutable and remove the objects first? like
Code:
-(void) dealloc
{
    for (object in self.myMutable)
    {
       [self.myMutable removeObject: object];
    }
    [self.myMutable release];  
}
roocell is offline   Reply With Quote
Old 04-24-2009, 03:18 PM   #22 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by roocell View Post
Code:
// are the next two lines ok to do ? wrt reference counts, etc.
self.myMutable= mutable_array;  
[mutable_array release];

}
Yes, assuming myMutable is a property with "retain" semantics. If it is "copy", then it's still OK from a memory management perspective, but just keep in mind that "copy" will give you an immutable copy, unless you provide your own setMyMutable method. The one you get for free with @synthesize will create an immutable copy.

Quote:
Code:
-(void) dealloc
{
    for (object in self.myMutable)
    {
       [self.myMutable removeObject: object];
    }
    [self.myMutable release];  
}
It's not necessary to do that. NSArray's own dealloc method will remove all objects (sending each of them releases)
eddietr is offline   Reply With Quote
Old 04-24-2009, 03:19 PM   #23 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 812
Default

The animationImages property in UIImageView is not copy, it is a retain. The ref count on the UIImage is not changed.

So, there is no problem with [myMutableArray release]. However, with your [myMutableArray removeAllObjects], the UIImageView contains no image.
johnqh is offline   Reply With Quote
Old 04-24-2009, 03:23 PM   #24 (permalink)
Registered Member
 
Join Date: Apr 2009
Posts: 536
Default

Quote:
Originally Posted by johnqh View Post
The animationImages property in UIImageView is not copy, it is a retain. The ref count on the UIImage is not changed.
The docs and the header say it is copy.
eddietr is offline   Reply With Quote
Old 04-24-2009, 04:16 PM   #25 (permalink)
Registered Member
 
Join Date: Nov 2008
Posts: 812
Default

Quote:
Originally Posted by eddietr View Post
The docs and the header say it is copy.
You are right. I goofed again.

I don't get why they would use copy at all. In any case, the OP's code should work. The removeAllObjects is not needed, but shouldn't crash.

OP, can you copy your exact code? I noticed

NSMutableArray *myMutableArray=[[NSMutableArray alloc] initWithCapacity:0]];

It has an extra "]". Did you have an autorelease on it?
johnqh is offline   Reply With Quote
Reply

Bookmarks

Tags
crash, low, memory, nsmutablearray, release

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Stats
Members: 158,884
Threads: 89,229
Posts: 380,763
Top Poster: BrianSlick (7,129)
Welcome to our newest member, karlam963
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 02:15 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0