我对块和 objective-c很新,我试图用两者写我的第一个类别.我的想法是在NSTimer上创建一个类别,它将接收一个块作为参数,这个块将用于选择器调用.现在我有这个. // NSTimer+Additions.h#import F
          // NSTimer+Additions.h
#import <Foundation/Foundation.h>
typedef void (^VoidBlock)();
@interface NSTimer (NSTimer_Additions)
+ (NSTimer *)scheduleTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions;
@end
#import "NSTimer+Additions.h"
static VoidBlock _voidBlock;
@interface NSTimer (AdditionsPrivate) // Private stuff
- (void)theBlock;
@end
@implementation NSTimer (NSTimer_Additions)
+ (NSTimer *)scheduleTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions {
    [_voidBlock release];
    _voidBlock = [actions copy];
    NSTimer* timer = [[NSTimer alloc] initWithFireDate:[NSDate date] 
                                          interval:theSeconds
                                            target:self 
                                          selector:@selector(theBlock) 
                                          userInfo:nil 
                                           repeats:repeats];
    [timer fire];
    return [timer autorelease];
}
- (void)theBlock {
    _voidBlock();
}
@end 
 代码要点:https://gist.github.com/1065235
一切都编译好但我有以下错误:
2011-07-05 14:35:47.068 TesteTimer [37716:903] *由于未捕获的异常’NSInvalidArgumentException’终止应用程序,原因:'[NSTimer theBlock]:无法识别的选择器发送到类0x7fff70bb0a18′
我该如何使这个类别工作?
除了错误的目标之外,你的主要缺陷是你使用静态变量.除了一个计时器,你将无法支持.使用block作为被调用方法的参数.
@interface NSTimer (AdditionsPrivate) // Private stuff
- (void)theBlock:(VoidBlock)voidBlock;
@end
@implementation NSTimer (NSTimer_Additions)
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions {
    NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:[self instanceMethodSignatureForSelector:@selector(theBlock:)]];
    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:theSeconds
                                                   invocation:invocation
                                                      repeats:repeats];
    [invocation setTarget:timer];
    [invocation setSelector:@selector(theBlock:)];
    Block_copy(actions);
    [invocation setArgument:&actions atIndex:2];
    Block_release(actions);
    return timer;
}
- (void)theBlock:(VoidBlock)voidBlock {
    voidBlock();
}
@end 
 使用关联引用的问题是泄漏,因为释放块没有好处.
早期的方法使用关联参考
您可以使用associative references将块附加到该特定NSTimer实例.
@implementation NSTimer (NSTimer_Additions)
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)theSeconds repeats:(BOOL)repeats actions:(VoidBlock)actions {
    NSInvocation * invocation = [NSInvocation invocationWithMethodSignature:[self instanceMethodSignatureForSelector:@selector(theBlock)]];
    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:theSeconds
                                                   invocation:invocation
                                                      repeats:repeats];
    [invocation setTarget:timer];
    [invocation setSelector:@selector(theBlock)];
    objc_setAssociatedObject(timer, @"Block", actions, OBJC_ASSOCIATION_COPY);
    return timer;
}
- (void)theBlock {
    VoidBlock _voidBlock = (VoidBlock)objc_getAssociatedObject(self, @"Block");
    _voidBlock();
}
@end
        
             