NSInvocation getReturnValue: called inside forwardInvocation: makes the returned object call dealloc:

南楼画角 提交于 2019-12-03 15:05:56

The problem is that result is __strong by default, so when it goes out of scope, the compiler generates a release for it. But getReturnValue: didn't give you ownership of the returned object, so your method shouldn't be releasing it.

You can fix this by changing the declaration of result:

__unsafe_unretained id result;

This prevents the compiler from generating a release for result when result goes out of scope. If you need to retain it, you can copy it to another, __strong variable.

You could also add a category to NSInvocation to handle this for you:

@interface NSInvocation (ObjectReturnValue)

- (id)objectReturnValue;

@end

@implementation NSInvocation (ObjectReturnValue)

- (id)objectReturnValue {
    __unsafe_unretained id result;
    [self getReturnValue:&result];
    return result;
}

@end

...
    if (length == 8) {
        id result = [invocation objectReturnValue];
    }
...

You could also report this as a bug. I would expect the compiler, or at least the static analyzer, to warn you that you're converting a pointer to a strong id to a void pointer. http://bugreport.apple.com

It was because ARC cannot manage objects which was written as pointers. Only directly assignment.

Wrong:

id result;
[invocation getReturnValue:&result];

Right:

void *pointer;
[invocation getReturnValue:&pointer];

id result = (__bridge id)pointer; //Correct, ARC will retain pointer after assignment
if (length == 8) {
    id result; //this is nil (its also a stack allocated pointer)
    [invocation getReturnValue:&result];  //sets the value to an object
}

...method ends object is deallocated

You must set the result to to a pointer which is not stack allocated or not call getReturnValue.

The API may assume that since you called getReturnValue that you are going to retain (and possibly consume the return value). You didnt. When you remove getReturnValue does the return value come back properly in the main method? The apple docs say that the return value is returned automatically.

Im assuming it does.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!