jrswizzle
jrswizzle copied to clipboard
Result of invocation in block is freed before it can be used
I attempted to swizzle the class method JSONObjectWithData:options:error:
like this:
+ (void)
load
{
static dispatch_once_t sInitToken;
dispatch_once(&sInitToken,
^{
__block NSInvocation* invocation = nil;
NSError* err = nil;
invocation = [self jr_swizzleClassMethod: @selector(JSONObjectWithData:options:error:)
withBlock:
^(id inObj, NSData* inData, NSJSONReadingOptions inOptions, NSError** outError)
{
NSLog(@"before %@", inObj);
NSInvocation* inv = [invocation copy];
[inv setArgument: &inData atIndex: 2];
[inv setArgument: &inOptions atIndex: 3];
[inv setArgument: &outError atIndex: 4];
[inv invokeWithTarget: inObj];
id ret = nil;
[inv getReturnValue: &ret];
NSLog(@"after %@", inObj);
return ret;
}
error: &err];
if (invocation == nil)
{
NSLogDebug(@"Error swizzling NSJSONSerialization: %@", err);
}
});
}
But unfortunately this doesn't seem to work, as the returned dictionary gets released before a later call to objc_retainAutoreleasedReturnValue()
deep inside iOS, causing a crash. Enabling Zombie objects shows:
*** -[__NSDictionaryI retain]: message sent to deallocated instance 0x600002611440
Interestingly, doing the same thing with regular methods works fine. I wonder if this is an ARC bug.
Have you found the solution, sir?
Wow, sorry, I can't even remember why I wrote this code.
I wrote this code was for testing in my script. I just found the invocation won't be released if I used a property to hold it. So it is not a problem now. Thanks anyway.