4

我正在尝试为objective-c 类制作一个好的基于块的初始化程序。我在超类中声明它,我希望它在所有子类中都有用。

现在我有:

+ (id)createWithBlock:(void (^) (id newObject))creationBlock {
    id newObject = [self object];    
    creationBlock(newObject);
    return newObject;
}

可以这样使用(在子类中):

Record *newRecord = [Record createWithBlock:^(id newObject) {
    Record *newRecord = (Record *)newObject;
    newRecord.name = @"Ginger";
    newRecord.type = @"Rhizome";
}];

现在还可以,但我希望能减少一点。理想情况下,它看起来像:

Record *newRecord = [Record createWithBlock:^{
    name = @"Ginger";
    type = @"Rhizome";
}];

但这似乎有点雄心勃勃。我也可以:

Record *newRecord = [Record createWithBlock:^(Record *newRecord) {
    newRecord.name = @"Ginger";
    newRecord.type = @"Rhizome";
}];

最后一个版本很困难,因为 clang 似乎对块进行了一些编译时类型检查。上面的内容不会与我上面的 createWithBlock: 的定义一起编译,因为:incompatible block pointer types initializing 'void (^)(struct Record *)', expected 'void (^)(struct objc_object *)

如果它没有进行这种强大的类型检查,我可以在运行时调整方法。(或者如果我 typedef 我的块声明,也许我现在可以这样做?)

一段时间以来,我一直在摸不着头脑,并且我已经阅读了几乎所有我能找到的块上的文档,包括 clang 规范。如果有人有想法,我很想听听,这是一个开源项目,我认为该模式将使所有 Objective-c 用户受益。

现在我的想法倾向于imp_implementationWithBlock(). 但随后我需要根据其中的内容“构建”一个新的 IMP,然后将其换掉。可行的?

4

1 回答 1

3

你用的是什么编译器?我相信最新版本的 LLVM 将接受您提供的最后一个代码示例。(即您给出的错误不应该发生。)

特别是,这对我在 Xcode 4.3.3 中的全新 Xcode 项目中使用 LLVM 3.1 有效。

于 2012-06-25T00:17:53.520 回答