_NSFireTimer crash

Member
Posts: 215
Joined: 2008.06
Post: #1
I'm having trouble debugging a crash that spits out this stack trace:

#0 0x905db688 in objc_msgSend
#1 0x922c920f in NSPopAutoreleasePool
#2 0x92302218 in __NSFireTimer
#3 0x928c5b45 in CFRunLoopRunSpecific
#4 0x928c5cf8 in CFRunLoopRunInMode
#5 0x31699d38 in GSEventRunModal
#6 0x31699dfd in GSEventRun
#7 0x30a5dadb in -[UIApplication _run]
#8 0x30a68ce4 in UIApplicationMain
#9 0x00001fd8 in main at main.m:14

I don't use Autorelease anywhere in my code other than in the "main.m" file that has the initial application's AutoreleasePool. The timer runs ONCE and then crashes when the selector it fires is finished. I can't figure out where to put breakpoints to debug or even where to start. All debugging up until now has shown that my NSTimer object is not nil at the end of the method call and everything should be working fine...

Any insight would be appreciated, thanks!

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #2
I may have found my issue, though I am unsure at this point:

I commented out some of my newer code and found that it works fine now. I have a [NSArray arrayWithArray:otherArray] call that seems to be the issue. It seems that arrayWithArray does a shallow copy, which is surprising and unfortunate. Code like so causes a crash:

Code:
NSArray * oneArray = [[NSArray alloc] init];

NSArray * otherArray  = [NSArray arrayWithArray: oneArray];

[oneArray release];

[otherArray release];

Because "arrayWithArray:" does a shallow copy, the release call on the otherArray will crash the application because it points to oneArray, which is already released. Please let me know if I am incorrect, but this is what appears to be happening.

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Member
Posts: 268
Joined: 2005.04
Post: #3
Talyn Wrote:I
Code:
NSArray * oneArray = [[NSArray alloc] init];

NSArray * otherArray  = [NSArray arrayWithArray: oneArray];

[oneArray release];

[otherArray release];

arrayWithArray returns an autoreleased object. It doesn't need to be released. So the next time through the event loop the autorelease pool tries to release the already freed object and causes the crash.
Quote this message in a reply
Member
Posts: 215
Joined: 2008.06
Post: #4
Bachus Wrote:arrayWithArray returns an autoreleased object. It doesn't need to be released. So the next time through the event loop the autorelease pool tries to release the already freed object and causes the crash.

Ah! Thank you! That's not as intuitive as I would like, but it's preferable to the shallow copy issue. Thanks again!

Mac users swear by their computers, PC users swear at their computers. ~Unknown

iSayz
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #5
Essentially, the only ObjC functions that return a retained object are +alloc, +new, -copy, -retain. If you didn't get the object from one of those, you must not -release it.
Quote this message in a reply
Member
Posts: 283
Joined: 2006.05
Post: #6
Whenever you have a class method that returns an instance of that class, by convention the return value is autoreleased. Usually the method contains the name of the class. So things like:

Code:
[NSString stringWithFormat:whatever];
[NSColor redColor];
[NSNull null];

Maybe not intuitive but once you notice the pattern it becomes easy to remember.
Quote this message in a reply
Post Reply