在我希望支持blocks的所有事情中,nsundomanager似乎没有这么做。这是有其内在原因吗?还是苹果公司根本就没有让这一点api现代化?
特别是我想在nsobject上定义一个方法,

- (void)performBlock {
    void (^block)(void) = (id)self;
    block();
}

为了能打电话,
[[undoManager prepareWithInvocationTarget:^{
    NSLog( @"hello world" );
}] performBlock];

我错过什么了吗?这有什么问题吗?
(灵感来源于2009年的Mike Asharticle,它建议不要在块上定义方法。我也在那里留下了评论。)

最佳答案

我认为mike的主要论点是它使得代码难以阅读,而不是说这个想法有一个根本的问题。
不过,我看到你写的有几个问题。首先,在nsobject上添加category方法,但是如果在不是块的对象上调用它,它将崩溃。也许有一种方法可以解决这个问题,比如让performBlock方法在调用一个非块,或者至少在崩溃之前记录一个错误时,什么都不做。我不知道这是怎么回事。
此外,块从堆栈开始,因此在将它们传递到一个方法中以备以后执行之前,需要复制它们。写一个块的方法来处理这个问题。可能-[NSUndoManager prepareWithInvocationTarget:]不会复制传入的目标。因此,在传递块之前,您需要自己复制它(使用-copyBlock_copy()):

void (^block)(void) = [^{
    NSLog(@"hello world");
} copy];

[[undoManager prepareWithInvocationTarget:block] performBlock];
[block release];

至少在arc的早期版本中,这仍然是一个问题,因为块被传递到一个期望id的方法中(如mike ash的ARC article的block s部分所解释)。也许已经修好了?我不会指望…

08-06 04:09