gpt4 book ai didi

objective-c - 为什么 protocol_* 方法不适用于 Clang + Linux 上的现代 GCC-Runtime?

转载 作者:太空狗 更新时间:2023-10-30 03:22:23 25 4
gpt4 key购买 nike

我试图将我的一些 Objective-C 项目从 GCC 切换到 Linux 上的 Clang。我使用 GCC 4.6.2 运行时,因为 Clang 编译器没有附带。编译和链接有效,但在使用 protocol_* 方法时它们不起作用。

以下示例适用于 GCC,但不适用于 Clang:

#include <objc/runtime.h>
#include <stdio.h>

@protocol MyProtocol
+ aClassMethod;
- anInstanceMethod;
@end

void doIt(Protocol *p, SEL sel)
{
printf("the protocol: %p\n", p);
if (!p) return;
printf("the protocol's name: %s\n", protocol_getName(p));
struct objc_method_description d = protocol_getMethodDescription(p, sel, YES, YES);
printf("required: YES instance: YES → %p\n", d.name);
d = protocol_getMethodDescription(p, sel, YES, NO);
printf("required: YES instance: NO → %p\n", d.name);
d = protocol_getMethodDescription(p, sel, NO, YES);
printf("required: NO instance: YES → %p\n", d.name);
d = protocol_getMethodDescription(p, sel, NO, NO);
printf("required: NO instance: NO → %p\n", d.name);
}

int main(int argc, char **argv)
{
Protocol *p1 = @protocol(MyProtocol);
printf("P1\n");
printf("class method first:\n");
doIt(p1, @selector(aClassMethod));
printf("instance method follows:\n");
doIt(p1, @selector(anInstanceMethod));

Protocol *p2 = objc_getProtocol("MyProtocol");
printf("P2\n");
printf("class method first:\n");
doIt(p2, @selector(aClassMethod));
printf("instance method follows:\n");
doIt(p2, @selector(anInstanceMethod));

printf("done\n");
return 0;
}

GCC 编译程序的预期输出:

P1
class method first:
the protocol: 0x804a06c
the protocol's name: MyProtocol
required: YES instance: YES → (nil)
required: YES instance: NO → 0x804b530
required: NO instance: YES → (nil)
required: NO instance: NO → (nil)
instance method follows:
the protocol: 0x804a06c
the protocol's name: MyProtocol
required: YES instance: YES → 0x804b528
required: YES instance: NO → (nil)
required: NO instance: YES → (nil)
required: NO instance: NO → (nil)
P2
class method first:
the protocol: 0x804a06c
the protocol's name: MyProtocol
required: YES instance: YES → (nil)
required: YES instance: NO → 0x804b530
required: NO instance: YES → (nil)
required: NO instance: NO → (nil)
instance method follows:
the protocol: 0x804a06c
the protocol's name: MyProtocol
required: YES instance: YES → 0x804b528
required: YES instance: NO → (nil)
required: NO instance: YES → (nil)
required: NO instance: NO → (nil)
done

Clang 编译程序的意外输出:

P1
class method first:
the protocol: 0x804a050
the protocol's name: (null)
required: YES instance: YES → (nil)
required: YES instance: NO → (nil)
required: NO instance: YES → (nil)
required: NO instance: NO → (nil)
instance method follows:
the protocol: 0x804a050
the protocol's name: (null)
required: YES instance: YES → (nil)
required: YES instance: NO → (nil)
required: NO instance: YES → (nil)
required: NO instance: NO → (nil)
P2
class method first:
the protocol: (nil)
instance method follows:
the protocol: (nil)
done

这是怎么回事?是否有一些神奇的初始化代码在使用 Clang 时不会被调用?

[更新]

当像下面这样添加协议(protocol)的实现时,objc_getProtocol() 方法有效,但 protocol_* 方法仍然无效。

@interface MyInstance <MyProtocol>
@end

@implementation MyInstance

+ aClassMethod
{
return nil;
}

- anInstanceMethod
{
return nil;
}

@end

最佳答案

在我的测试中,GCC 与它包含的 GNU libobjc 一起工作得很好,但 Clang 与 GNUstep libobjc2 一起工作得更好。

带有 GNU libobjc 的 GCC 4.6:通过

P1class method first:the protocol: 0x602120the protocol's name: MyProtocolrequired: YES instance: YES → (nil)required: YES instance: NO → 0x10eda50required: NO instance: YES → (nil)required: NO instance: NO → (nil)instance method follows:the protocol: 0x602120the protocol's name: MyProtocolrequired: YES instance: YES → 0x10eda40required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)P2class method first:the protocol: 0x602120the protocol's name: MyProtocolrequired: YES instance: YES → (nil)required: YES instance: NO → 0x10eda50required: NO instance: YES → (nil)required: NO instance: NO → (nil)instance method follows:the protocol: 0x602120the protocol's name: MyProtocolrequired: YES instance: YES → 0x10eda40required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)done

带有 libobjc2 1.6 的 GCC 4.6:失败

P1class method first:the protocol: 0x602120the protocol's name: MyProtocolrequired: YES instance: YES → (nil)required: YES instance: NO → 0x6020a0required: NO instance: YES → (nil)required: NO instance: NO → (nil)instance method follows:the protocol: 0x602120the protocol's name: MyProtocolrequired: YES instance: YES → 0x6020b0required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)P2class method first:the protocol: (nil)instance method follows:the protocol: (nil)done

带有 GCC 4.6 GNU libobjc 的 Clang 3.1:失败

P1class method first:the protocol: 0x602080the protocol's name: (null)required: YES instance: YES → (nil)required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)instance method follows:the protocol: 0x602080the protocol's name: (null)required: YES instance: YES → (nil)required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)P2class method first:the protocol: (nil)instance method follows:the protocol: (nil)done

带有 libobjc2 1.6 的 Clang 3.1:通过

P1class method first:the protocol: 0x602080the protocol's name: MyProtocolrequired: YES instance: YES → (nil)required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)instance method follows:the protocol: 0x602080the protocol's name: MyProtocolrequired: YES instance: YES → (nil)required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)P2class method first:the protocol: 0x602080the protocol's name: MyProtocolrequired: YES instance: YES → (nil)required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)instance method follows:the protocol: 0x602080the protocol's name: MyProtocolrequired: YES instance: YES → (nil)required: YES instance: NO → (nil)required: NO instance: YES → (nil)required: NO instance: NO → (nil)done

关于objective-c - 为什么 protocol_* 方法不适用于 Clang + Linux 上的现代 GCC-Runtime?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10314035/

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