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

performSelectorWithArgs 内存管理问题 #51

Open
rollingstoneW opened this issue Jun 11, 2018 · 1 comment
Open

performSelectorWithArgs 内存管理问题 #51

rollingstoneW opened this issue Jun 11, 2018 · 1 comment

Comments

@rollingstoneW
Copy link

使用performSelectorWithArgs获取返回的对象,会直接释放
在getReturnFromInv:withSig:方法里
case '@': { // id
id ret = nil;
[inv getReturnValue:&ret];
return ret;
};
如果在id前面加上__autoreleasing就没有问题了,但是不知道具体原因是什么

@lyandy
Copy link

lyandy commented Nov 21, 2018

使用performSelectorWithArgs获取返回的对象,会直接释放
在getReturnFromInv:withSig:方法里
case '@': { // id
id ret = nil;
[inv getReturnValue:&ret];
return ret;
};
如果在id前面加上__autoreleasing就没有问题了,但是不知道具体原因是什么

原因是在arc模式下,getReturnValue:仅仅是从invocation的返回值拷贝到指定的内存地址,如果返回值是一个NSObject对象的话,是没有处理起内存管理的。而我们在定义returnValue时使用的是__strong类型的指针对象,arc就会假设该内存块已被retain(实际没有),当returnValue出了定义域释放时,导致该crash。假如在定义之前有赋值的话,还会造成内存泄露的问题。

NSObject *returnValue = nil;
// 有返回值类型,才去获得返回值
if (signature.methodReturnLength != 0)
{
void *tempReturnValue;
[invocation getReturnValue:&tempReturnValue];
returnValue = (__bridge NSObject *)tempReturnValue;
}
response(returnValue, nil);

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