This piece of codes segment fault on me, any idea why? allButtons
is a NSMutableArray
, it contains 3 objects, a=0, b=1
, a a开发者_开发技巧nd b are int
type
if(a != -1 && b!= -1){
//Swap index in "allButtons"
id tempA = [allButtons objectAtIndex:a];
id tempB = [allButtons objectAtIndex:b];
[allButtons replaceObjectAtIndex:a withObject:tempB]; //Seg fault here?????
[allButtons replaceObjectAtIndex:b withObject:tempA];
needLoad = false;
[self setUpButtons];
}
EDIT:
NSMutableArray *allButtons = //fetch the array from Coredata. This work since I display the data onto the screen, plus, [allButtons count] return 3, and a=0, b=1
f(a != -1 && b!= -1){
//Swap index in "allButtons"
[allButtons exchangeObjectAtIndex:a withObjectAtIndex:b];
needLoad = false;
[self setUpButtons];
}
The first call to replaceObjectAtIndex:
will release the old object (tempA
), but that shouldn't cause a seg fault. As @Zoran mentioned try logging the retainCount
for tempA and verify its count.
Also for swapping elements in an array, you should use exchangeObjectAtIndex:withObjectAtIndex
instead of replaceObjectAtIndex:withObject
. It's supported from iPhone 2.0.
Just because you have said
NSMutableArray *allbuttons = // something
doesn't mean that it is definitely an NSMutableArray, it just means that the compiler thinks that it will be a NSMutableArray.
If it's from CoreData, it's probably just an NSArray
so the method calls you are trying won't work - you'll get unrecongnised selector or something like that.
You will have to convert it to a mutable array first
NSArray *coreData = // core data call
// Create a mutable copy
// NB This means that you are now working on a copy, not the original :)
NSMutableArray *allButtons = [coreData mutableCopy];
tempA
is going to be released when you call the first replaceObjectAtIndex
. Keep that in mind when calling this... I have no idea why releasing tempA
would seg fault for you, examine what its dealloc
does perhaps.
Check the retain count of tempA
to verify that it is indeed dealloc-ed (not simply released) by the call to replaceObjectAtIndex
like so:
id tempA = [allButtons objectAtIndex:a];
NSLog(@"retain count for tempA: %i", [tempA retainCount]);
If you see a retain count of 1 at this level, then your object tempA
is being dealloc-ed by the call to replaceObjectAtIndex
Please read and understand the Cocoa rules on object ownership. Note that you have not claimed ownership over the objects referenced by tempA and tempB and you must therefore heed the following:
A received object is normally guaranteed to remain valid within the method it was received in ... (although you must also take care if you modify an object from which you received another object). That method may also safely return the object to its invoker.
Basically, the line:
[allButtons replaceObjectAtIndex:a withObject:tempB];
May cause tempA to be deallocated. This means that the subsequent line will cause allButtons to send a retain message to an invalid object, hence the seg fault. To fix the problem, you need to retain tempA before the swap and release it or autorelease it after.
NB it's wise to forget about retain counts. Unless you are fully aware of the implementation of all objects that touch your objects, you cannot make any assumptions about what the retain count of an object is. For instance, there's no rule that says that the implementation of NSMutableArray will only ever retain its elements once.
Use this method pass the appropritate index
exchangeObjectAtIndex:withObjectAtIndex:
精彩评论