Objective c 弧形桥铸块复制和;块释放

Objective c 弧形桥铸块复制和;块释放,objective-c,ios,automatic-ref-counting,Objective C,Ios,Automatic Ref Counting,出于某种原因,我希望在运行循环的下一次迭代中执行一个块,因此我提出: typedef void (^resizer_t)() ; - (void) applyResizer: (resizer_t) resizer { resizer() ; Block_release(resizer) ; } - (void) usage { ... resizer_t resizer = ^() { // stuff } ; [self

出于某种原因,我希望在运行循环的下一次迭代中执行一个块,因此我提出:

typedef void (^resizer_t)() ;

- (void) applyResizer: (resizer_t) resizer {
    resizer() ;
    Block_release(resizer) ;
}

- (void) usage {
    ...
    resizer_t resizer = ^() {
        // stuff
    } ;

    [self performSelectorOnMainThread:@selector(applyResizer:)
                           withObject:(__bridge id) Block_copy((__bridge void *) resizer)
                        waitUntilDone:NO] ;
}
  • 我不得不放弃这个论点,这不是很讽刺吗 块拷贝
  • 为什么编译器对我的Block_发布感到满意 在块拷贝上没有桥空*铸造

  • 代码似乎正常工作,我没有检测到泄漏或过早发布,但语法让我有点困惑…

    块被视为对象,因此在没有显式桥接强制转换的情况下,可以防止将它们强制转换为
    void*
    。奇怪的是,你的编译器并没有抱怨
    块发布版
    :它应该抱怨(在我的机器上,它抱怨)

    因为ARC将块视为对象,所以您不需要再使用
    block\u copy
    block\u release
    。复制块(使用
    -[NSObject Copy]
    )以将其移动到堆中,并让编译器管理其余部分

    -[NSObject performSelectorOnMainThread:withObject:waitUntilDone:][/code>将保留接收方和参数对象,直到调用该方法为止。因此,您的块将在需要时保留和释放。您所要做的就是在将块传递给方法之前,通过发送
    copy
    消息来确保块没有存储在堆栈上

    此外,还有一种更简单的方法来调度块的执行:libdispatch(又名GCD)

    我希望在运行循环的下一次迭代中执行一个块

    好吧,这就是为什么你在
    之后有了
    dispatch\u。如果您提供一个很小的时间值,它将产生与您所追求的效果完全相同的效果:您给出一个块,并且该块将在当前runloop完成并且重画时刻发生时立即执行

    或者,如果您可以在不坚持使用块的情况下生存,请使用带有微小延迟值(甚至为零)的
    性能选择器:withObject:afterDelay:
    。这也有同样的效果


    你所要求的是所谓的“延迟性能”,这是很常见的。因此,按照框架提供给您的常用方式进行操作;不要像你的代码那样试图变得怪异和花哨。

    答案很清楚。我还建议@verec对主队列使用dispatch_async。
    dispatch_async(dispatch_get_main_queue(), resizer);