gpt4 book ai didi

objective-c - 如何在 Objective-c 中获取运行时 block 类型元数据?

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

我正在编写一个类,您可以在其中注册一个对象和一个要观察的属性。当属性设置为非 nil 时,将调用已注册的回调选择器(如目标操作)。选择器可能有三种不同的签名,根据注册的类型调用正确的签名。

这很好用,但现在我想添加将 Block 而不是选择器注册为“回调函数”的功能。是否可以找出所提供 Block 的函数签名并根据所提供 Block 的类型以不同方式处理回调?

例如:

- (void)registerCallbackBlock:(id)block
{
if ([self isBlock:block] {
if ([self isMethodSignatureOne:block]) { /* */ }
else if ([self isMethodSignatureTwo:block]) { /* */ }
else { assert(false); } // bad Block signature

block_ = block; // assuming ARC code
}
else { assert(false); } // not a block
}

- (void)callBlock
{
if ([self isMethodSignatureOne:block_] {
block_(arg1_, arg2_); // needs casting?
}
else if ([self isMethodSignatureTwo:block_) {
block_(arg1_, arg2_, arg3_); // needs casting?
}
}

有什么想法吗?

我知道我可以使用特定的 typedef'ed Block 参数创建不同的寄存器函数,但如果可能的话,我宁愿使用一个函数。

最佳答案

如果您使用 clang 进行编译,您可以获得此信息。

来自Clang block ABI spec :

The ABI of blocks consist of their layout and the runtime functions required by the compiler. A Block consists of a structure of the following form:

struct Block_literal_1 {
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor_1 {
unsigned long int reserved; // NULL
unsigned long int size; // sizeof(struct Block_literal_1)
// optional helper functions
void (*copy_helper)(void *dst, void *src); // IFF (1<<25)
void (*dispose_helper)(void *src); // IFF (1<<25)
// required ABI.2010.3.16
const char *signature; // IFF (1<<30)
} *descriptor;
// imported variables
};

The following flags bits are in use thusly for a possible ABI.2010.3.16:

enum {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE
BLOCK_HAS_SIGNATURE = (1 << 30),
};

实际上,当前版本的 clang 确实对签名信息进行了编码。根据评论here ,格式只是一个标准的 objective-c 方法编码字符串。也就是说,签名格式没有记录(据我所知),所以我不确定您可以在多大程度上假设它不会因编译器更新而中断。

关于objective-c - 如何在 Objective-c 中获取运行时 block 类型元数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6624361/

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