views:

309

answers:

2

I am building a game that pulls images randomly. After doing some testing I have realized if the same image is called twice, it crashes. I learned this by after completing the first game, I returned to the games main menu and selected to play again. I ended up getting an image which was already displayed to me in my previous game and a second later my app crashed. I did some testing and made the same image show up twice during my first game, and it crashed a second after the image was displayed a second time.

Here is a sample code. "idNum" and "timer" are declared in the .h file so they are global. As you can see I have NSTimer that runs every second to randomize a new image to be pulled. Works find until an image is trying to be shown for a second time. Say I get a random order of 1,3,2,5,3. It will crash on the second 3.

Can you not call an image twice? I can only think that this is a caching issue, I am not sure how to release the image cache. I get the error objc_msgSend. Sorry not very good at debugging crashes.

//idNum = the randomly generated integer
//pictures are called by numbers ex(1.jpg, 5.jpg)



timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timeCounter) userInfo:nil repeats:YES];


-(void)timeCounter {
time = time + 1;

    idNum = (arc4random() % 5);

    NSString * imgIDnum = [[NSString alloc] initWithFormat:@"%d", idNum];
    imgMain = [NSString stringWithFormat:@"%@%@", imgIDnum, @".jpg"];
    [imgIDnum release];

    UIImage * daImg = [UIImage imageNamed:imgMain];
    [imgView setImage:daImg];



  }
A: 

You should provide more information about the crash. Is it in the +imageNamed: line above, or perhaps in -setImage:?

The most likely cause is that you are over-releasing the UIImage. For instance, if you're calling [daImg release] after the above code, then you would get this behavior because you would be over-releasing something that the UIImage class is caching. This wouldn't cause a crash until the situation you describe.

I've seen a really entertaining version of this bug: a teammate of mine was over-releasing an NSNumber (it happened to be for the integer 2 most of the time). NSNumbers are cached internally, so the next time he created an NSNumber for the integer 2, in an unrelated part of the program, it would crash. Any other number was fine, but try to NSLog() a 2, and boom.

Rob Napier
Yeah that is very similar to what is happening here. I randomize numbers that correspond to a jpg, and once I reach a jpg that has already been select before it crashes on me. Is there an easy way to remove the image from being cached? I dont need a cached image.
bbullis21
First, fix your over-release. The problem is not the cache; it's your memory management. Then, if you don't want caching, don't use +imageNamed:. It is explicitly for caching images. Read "Images and Memory Management" in UIImage for more information, as well as the documentation on +imageNamed:.
Rob Napier
I tried removing the [daImg release] in my code and that didn't make a difference. I still got the same result the second time the image was displayed.
bbullis21
Is imgMain an ivar? You're failing to retain it, which could well be causing an unrelated crash. If imgMain and timer are ivar, then you need to learn about using accessors. Never talk to ivars directly (except in accessors and perhaps in dealloc). Always use an accessor. You will save yourself a lot of crashes. http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAccessorMethods.html
Rob Napier
A: 

Well I am sorry to say that I have fixed the issue and have no idea how. I ended up re-writing majority of that code, adding, removing and changing some snippets around to be more memory management friendly. When I went to run it again things were perfectly fine. Sorry for no solution. If someone else comes across this problem, let me know I will try and help.

bbullis21