Ken*_*ins 12 cocoa objective-c objective-c-blocks
我想通过为Objective-C Blocks创建一个类别来添加函数.
__block int (^aBlock)(int) = ^int( int n ){
if( n <= 1 ) return n;
return aBlock( n - 1 ) + aBlock( n - 2 );
};
Run Code Online (Sandbox Code Playgroud)
而不是只允许正[aBlock copy],[aBlock retain],[aBlock release],[aBlock autorelease].我可以这样做:
[aBlock mapTo:anArray];
Run Code Online (Sandbox Code Playgroud)
可能的类别
@interface UnknownBlockClass (map)
- (NSArray *)mapTo:(NSArray *)array_;
@end
Run Code Online (Sandbox Code Playgroud)
Dav*_*ong 13
@pwc是正确的,因为你无法为你看不到的类创建一个类别.
然而...
__NSStackBlock,__NSMallocBlock,__NSAutoBlock,和NSBlock.NSBlock因此看起来任何块都将成为某个实例或子类NSBlock.
您可以在对象上创建方法,如下所示:
@implementation Foo
- (void) doFoo {
//do something awesome with self, a block
//however, you can't do "self()".
//You'll have to cast it to a block-type variable and use that
}
@end
Run Code Online (Sandbox Code Playgroud)
然后在运行时,您可以将该方法移动到NSBlock该类:
Method m = class_getInstanceMethod([Foo class], @selector(doFoo));
IMP doFoo = method_getImplementation(m);
const char *type = method_getTypeEncoding(m);
Class nsblock = NSClassFromString(@"NSBlock");
class_addMethod(nsblock, @selector(doFoo), doFoo, type);
Run Code Online (Sandbox Code Playgroud)
在此之后,块应响应该doFoo消息.
一个块最终成为类型的实例__NSGlobalBlock__,如下面的代码片段所示:
void (^aBlock)(void) = ^(void) {
NSLog(@"Hello world");
};
// prints "type = __NSGlobalBlock__"
NSLog(@"type = %@", [aBlock class]);
为了创建类的类,编译器需要能够看到类的原始@interface声明.我找不到声明__NSGlobalBlock__,也许是有充分理由的.
至于你原来的观点,为什么不NSArray为你的mapTo方法做一个类别?对于那种功能来说,这似乎是一个更好的地方.
更新
假设您可以向Block对象添加类别.你会如何从类别的方法中调用块?据我所知,调用块的唯一方法是通过()运算符(例如aBlock()).我不认为有一种方法可以从Block对象中分辨出参数的数量和类型.那么,你将什么参数传递给块调用?
我不建议你这样做,但以下工作......
@interface NSObject (BlockExtension)
- (void)foo;
@end
@implementation NSObject (BlockExtension)
- (void)foo
{
// not sure how else to determine if self is a Block since neither
// __NSGlobalBlock__ nor any of its superclasses (except NSObject)
// are accessible to the compiler
if ([[[self class] description] isEqual:@"__NSGlobalBlock__"])
{
NSLog(@"foo");
// now what?
// can't call self(), it doesn't compile
// how else can I invoke this block?
}
}
@end
...
void (^aBlock)(void) = ^(void) {
NSLog(@"Hello world");
};
// prints "foo"
[aBlock foo];