Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Result of invocation in block is freed before it can be used #22

Open
JetForMe opened this issue Feb 27, 2019 · 4 comments
Open

Result of invocation in block is freed before it can be used #22

JetForMe opened this issue Feb 27, 2019 · 4 comments

Comments

@JetForMe
Copy link

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
@JetForMe
Copy link
Author

Interestingly, doing the same thing with regular methods works fine. I wonder if this is an ARC bug.

@zhongshucheng
Copy link

Have you found the solution, sir?

@JetForMe
Copy link
Author

Wow, sorry, I can't even remember why I wrote this code.

@zhongshucheng
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants