Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 带块的NSUndoManager_Objective C_Cocoa_Objective C Blocks_Block_Nsundomanager - Fatal编程技术网

Objective c 带块的NSUndoManager

Objective c 带块的NSUndoManager,objective-c,cocoa,objective-c-blocks,block,nsundomanager,Objective C,Cocoa,Objective C Blocks,Block,Nsundomanager,奇怪的是,在我期望支持块的所有东西中,NSUndoManager似乎并没有这样做。这有什么内在的原因吗?或者苹果根本就没有让这一点API现代化 我特别想在NSObject上定义一个方法 - (void)performBlock { void (^block)(void) = (id)self; block(); } 为了能够打电话 [[undoManager prepareWithInvocationTarget:^{ NSLog( @"hello world" );

奇怪的是,在我期望支持块的所有东西中,NSUndoManager似乎并没有这样做。这有什么内在的原因吗?或者苹果根本就没有让这一点API现代化

我特别想在NSObject上定义一个方法

- (void)performBlock {
    void (^block)(void) = (id)self;
    block();
}
为了能够打电话

[[undoManager prepareWithInvocationTarget:^{
    NSLog( @"hello world" );
}] performBlock];
我错过什么了吗?这有什么问题吗


(受2009年Mike Ash的启发,他建议不要在块上定义方法。我也在那里留下了一条评论。)

我认为Mike的主要论点是,这会导致代码难以阅读,而不是这个想法存在根本问题

然而,我发现你所写的有几个问题。首先,您正在NSObject上添加一个category方法,但如果您在非块的对象上调用它,它将崩溃。也许有一种方法可以解决这个问题,比如让
performBlock
方法在非块上调用时什么都不做,或者至少在崩溃之前记录一个错误。我不知道这到底是怎么回事

此外,块是从堆栈开始的,因此在将它们传递到一个方法之前,您需要先复制它们,该方法将保留这些块以便以后执行。为获取块而编写的方法会处理此问题。大概
-[nsondomanager prepareWithInvocationTarget:
不会复制传入的目标。因此,在传入块之前,您需要自己复制块(使用
-copy
block\u copy()
):

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

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

至少在ARC的早期版本中,这仍然是一个问题,因为块被传递到一个需要
id
(如Mike Ash的Blocks部分所述)的方法中。也许已经修好了?我不指望……

完全同意。我可以想象它在库比蒂诺总部的一些内部待办事项清单上,最后一次被丢弃。。。3由于其他原因导致的操作系统发布。在API中使用块似乎是一件很容易的事。仅供参考-在iOS 9.0和OS X 10.11中,基于块的撤销被添加到了
NSUndoManager