gpt4 book ai didi

objective-c - 运行时编程动态方法时使用 ARC 编译时出错

转载 作者:搜寻专家 更新时间:2023-10-30 20:06:13 28 4
gpt4 key购买 nike

我正在尝试在 Objective-C 上进行一些运行时编程。为此,我覆盖了 resolveClassMethod 方法。

不幸的是,当 ARC 处于事件状态时,我发现了一些编译错误:

error: no known class method for selector 'dynamic'

如果我在没有 ARC 的情况下使用 gcc 或 clang(-fno-objc-arc 选项已通过),一切正常,除了警告而不是错误。

我知道 ARC 需要知道被调用的方法的名称,以确定如何使用返回值管理内存(遵循方法名称约定)。但是如何在没有丑陋的 performSelector 调用而不是直接方法调用的情况下解决这个问题?

这是我的代码:

测试.m

#import "Test.h"
#import <objc/runtime.h>

NSString* dynamicImp(id slef, SEL _cmd)
{
NSLog(@"Dynamic method called");
return @"dynamicImp";
}

@implementation Test

- (NSString*)name
{
return @"John";
}

+ (BOOL)resolveClassMethod:(SEL)name
{
if (name == @selector(dynamic))
{
Class metaClass = objc_getMetaClass([NSStringFromClass([self class]) UTF8String]);
class_addMethod(metaClass, name, (IMP) dynamicImp, "@@:");
return YES;
}
return NO;
}

+ (IMP)methodForSelector:(SEL)aSelector
{
if (aSelector == @selector(dynamic))
{
return (IMP) dynamicImp;
}
else
{
return [super methodForSelector:aSelector];
}
}

- (BOOL)respondsToSelector:(SEL)aSelector
{
if (aSelector == @selector(dynamic))
{
return YES;
}
else
{
return [NSObject respondsToSelector:aSelector];
}
}

@end

测试.h

#import <Cocoa/Cocoa.h>

@interface Test : NSObject <NSObject> {
NSString *_name;
}

- (NSString*)name;

@end

ma​​in.m

#import <Cocoa/Cocoa.h>
#import <stdio.h>
#import "Test.h"

int main(int argc, char* argv[])
{
@autoreleasepool {
Test *test = [[Test alloc] init];
NSLog(@"Hello, %@", [test name]);
NSLog(@"How are you , %@", [Test dynamic]);
}
return 0;
}

没有 ARC 的 Gcc 或 clang

编译结果

main.m:13:36: warning: class method '+dynamic' not found (return type defaults to 'id')

    NSLog(@"How are you , %@", [Test dynamic]);

输出

2012-10-22 10:33:15.563 test-clang[957:707] Hello, John 2012-10-22

2012-10-22 10:33:15.565 test-clang[957:707] Dynamic method called 2012-10-22

2012-10-22 10:33:15.565 test-clang[957:707] How are you , dynamicImp

带 ARC 的 Clang

编译结果

main.m:13:36: error: no known class method for selector 'dynamic'

    NSLog(@"How are you , %@", [Test dynamic]);

PS:我暂时不关心内存管理,因为我的目标是在激活 ARC 的情况下编译这段代码。

最佳答案

在你的通话中

NSLog(@"How are you , %@", [Test dynamic]);

ARC 编译器不知道方法的返回类型。但是 ARC 需要知道该方法是否返回对象以添加适当的retain/release 调用来管理生命周期。

即使没有 ARC,您也会收到编译器警告

class method '+dynamic' not found (return type defaults to 'id')

但是 ARC 编译器更严格。

你可以调用

NSLog(@"How are you , %@", [[Test class] performSelector:@selector(dynamic)]);

因为 performSelector 返回一个 id。对于返回除对象之外的任何内容的函数,您可以使用 NSInvocation

或者,您可以使用类扩展声明动态方法:

@interface Test (DynamicMethods)
+ (NSString *)dynamic;
@end

关于objective-c - 运行时编程动态方法时使用 ARC 编译时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13007797/

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