I got the "objc_msgSend()" killer error message in my app and thanks to Hamster Emporium i can figure out a little bit what was happening.
Now i found the "problem" and the "solution", but what i can't understand why my problem was really a problem.
Here is the scenario:
Object_A --> Object_B --> Object_C
The '-->' symbol represent the "create" action. Class of Object_C looks like this:
@interface Class_C {
NSArray *items;
}
@property (nonatomic,开发者_StackOverflow中文版 retain) NSArray *tems;
@end
The property 'items' is set in Object_B through a 'setItems' method:
- (void)setItems:(NSArray *)items_ {
if (object_B) {
[object_B.taskItems release];
object_B.taskItems = items_;
}
[super setItems:items_];
}
Now, if I use this method as is I got the blasphemous 'objc_msgSend()' error BUT if I comment the release line everything goes well.
Note: the retainCount in the release line is 0, but the release execute without problems
You are getting that error because the taskItems
member variable is being released twice. There is no need to manually release taskItems
because using the dot syntax takes care of it automatically.
This line:
object_B.taskItems = items;
Invokes the property accessor for taskItems
, in which the old value is automatically released before the new one is retained (or copied, depending on the property definition).
A very good general rule for Cocoa memory management is that you should only release
an object if you created it (either by alloc/init or by copy). Releasing object_B.taskItems
would violate that rule.
Uhm, wow. ok.
object_B.taskItems = items_;
is the same as calling
[object_B setTastItems: items_];
if taskItems
is a property set to retain, you don't need to release it first since the property will do so. The way you have your code right now, it gets released twice.
Remember, properties are not the same as members in Objective-C. Properties are methods which access the private members of the class (and do fancy stuff like retain/release
and @synchronized
).
I had a similar problem, but in my case this was the scenario:
I made a controller that registers itself to listen for changes in a NSOperation attribute "isFinished", while the NSOperation was working my controller went away, when the NSOperation finished and tried to notify:
[self willChangeValueForKey:@"isFinished"];
I got
objc_msgSend() corrupt cache error
But it was because my Controller was out of scope, to fix it I wait for the results of NSOperation KVO and then move to next controller.
精彩评论