我正在尝试为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 *)
。
如果没有进行强类型检查,我可以在运行时调用方法。 (或者,如果我输入我的块声明,我现在可以做到这一点吗?)
我一直在摸不着头脑,我已经阅读了几乎所有关于我能找到的块的文档,包括clang规范。如果有人有我想听的想法,这是一个开源项目,我认为这种模式将使所有Objective-c用户受益。
现在我的想法倾向于imp_implementationWithBlock()
。但后来我需要根据那个中的内容“构建”一个新的IMP,并将其交换掉。可行?
答案 0 :(得分:3)
您使用的是什么编译器?我相信最新版本的LLVM将接受您提供的最后一个代码示例。 (即你不应该犯错误。)
特别是,这适用于我在Xcode 4.3.3中的全新Xcode项目中使用LLVM 3.1。