gpt4 book ai didi

objective-c - NSInvocation 获取返回值 : called inside forwardInvocation: makes the returned object call dealloc:

转载 作者:太空狗 更新时间:2023-10-30 03:39:07 26 4
gpt4 key购买 nike

这是我用来测试行为的独立 test.m 文件。

编译:clang test.m -o test.app -fobjc-arc -ObjC -framework Foundation。确保已安装 Xcode 命令行工具。

#import <Foundation/Foundation.h>

@protocol Protocol

@optional
- (id)objProxyMethod;

@end

@interface ReturnObject: NSObject

@end

@interface Test : NSObject <Protocol>

@end

@interface Proxy : NSObject <Protocol>

- (id)objProxyMethod;

@end

@implementation ReturnObject

- (void)dealloc {
NSLog(@"ERROR:");
NSLog(@"I'm getting deallocated!");
NSLog(@"This shouldn't happen!");
}

- (NSString *)description {
return @"Blank object!";
}

@end

@implementation Proxy

- (id)objProxyMethod {
NSLog(@"in [Proxy objProxyMethod]!");
return [[ReturnObject alloc] init];
}

@end

@implementation Test

- (void)forwardInvocation:(NSInvocation *)invocation {
NSLog(@"Forwarded invocation!");
Proxy *proxy = [[Proxy alloc] init];
[invocation invokeWithTarget: proxy];
NSUInteger length = [[invocation methodSignature] methodReturnLength];
if (length == 8) {
id result;
[invocation getReturnValue:&result];
}
}

@end

int main () {
Test *test = [[Test alloc] init];
id objResult = [test objProxyMethod];
NSLog(@"objResult = \"%@\"", objResult);

return 0;
}

如果我注释掉 [invocation getReturnValue:&result];,则返回的对象不会被释放。我不知道这是一个错误,还是我误解了 NSInvocation 的工作原理。

最佳答案

问题是 result 默认是 __strong,所以当它超出范围时,编译器会为它生成一个 release。但是 getReturnValue: 没有给你返回对象的所有权,所以你的方法不应该释放它。

您可以通过更改result 的声明来解决此问题:

__unsafe_unretained id result;

这可以防止编译器在 result 超出范围时为 result 生成 release。如果需要保留它,可以将其复制到另一个 __strong 变量。

您还可以向 NSInvocation 添加一个类别来为您处理此问题:

@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];
}
...

您也可以将此报告为错误。我希望编译器或至少是静态分析器警告您,您正在将指向强 id 的指针转换为 void 指针。 http://bugreport.apple.com

关于objective-c - NSInvocation 获取返回值 : called inside forwardInvocation: makes the returned object call dealloc:,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11874056/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com