开发者

Printing an NSMutableArray causes crash with no error code

I determined that my application crashes on the following line:

if(sourceValues != nil && [sourceValues class] == [NSMutableArray class])
    [sourceValues release];

"sourceValues" is declared as an NSMutableArray at the top of my class. The "if" loop is satisfied, and the [sourceValues release] call gets made, which crashes the program with no error code. So,开发者_如何转开发 since sourceValues != nil and since [sourceValues class] == [NSMutableArray class], I wanted to see exactly what sourceValues was. So, above the "if" loop I added the following:

NSLog(@"sourceValues is %@", sourceValues);

But my program will not print it. It just crashes with no error code on that line. So, if sourceValue exists and if it an NSMutableArray, why will it not be printed. What is the problem here?

I'm trying to have code that says "if sourceValues has been allocated, release it." How can I do this?


Why not use:

if(sourceValues != nil && [sourceValues isKindOfClass:[NSMutableArray class]])
    [sourceValues release];

You may want to use other methods like:

  • isMemberOfClass:


If this...

NSLog(@"sourceValues is %@", sourceValues);

... is crashing your program, it is because sourceValues has already been released. Wherever you release sourceValues, set it to nil.

[sourceValues release], sourceValues = nil;

If your app is still crashing, it is because the array has been over-released somewhere else. That is, you didn't correctly balance retains and releases. First, try "build and analyze" and fix any problems the static analyzer identifies. Next, turn on zombie detection and see where you are first messaging the over-released object.

Note that [sourceValues class] == [NSMutableArray class] will not work and that pattern should never be used to check if an instance is of a particular class. You should always use isKindOfClass: or isMemberOfClass:.

However, since you can't tell the difference between a mutable or immutable array anyway, there is no point to checking in the first place.


Well, first off, there's no danger in releasing a nil object. So the issue of "if sourceValues has been allocated, release it." is probably superfluous. Unless you're doing some funky stuff, you should follow regular memory management rules and just call [sourceValues release]; in dealloc

Have you tried running everything with breakpoints on ("Build and Debug - Breakpoints On" in Xcode)? That usually gives you more debug information than the usual "Build and run".

It might be (I'm guessing based on some odd problems I've had in the past) that you've actually dealloced sourceValues already but the pointer is still pointing to its old memory. If that happens, a new object might be situated in that area which the program will attempt to treat like an NSMutableArray anyway.


Try checking the retainCount, something like:

NSLog(@"retain count: %d", [sourceValues retainCount]);

ONLY use for testing/debugging, don't rely on this in an if statement.

Also, you can try iterating over sourceValues and print its contents to NSLog, but I have no idea what's in there.

BEST thing to do is setup a class property as an MSMutableArray with RETAIN, and use synthesize. The dealloc will take care of the release.

If the above is implemented, you can alloc/init as follows:

self.sourceValues = [[[NSMutableArray alloc] init] autorelease];

and then add objects directly to self.sourceValues as needed. No need to worry about releasing, it will be done in dealloc.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜