beginSheet: block alternative with ARC?

独自空忆成欢 提交于 2019-12-04 07:27:18

ARC doesn’t like conversions to void *, which is what the Block_* functions expect as arguments, because ARC cannot reason about ownership of non-retainable types. You need to use bridge casts to tell ARC how it should manage the ownership of the objects involved, or that it shouldn’t manage their ownership at all.

You can solve the ARC issues by using the code below:

- (void)beginSheet:(NSWindow *)sheet
    modalForWindow:(NSWindow *)docWindow
       didEndBlock:(void (^)(NSInteger returnCode))block
{  
    [self beginSheet:sheet
       modalForWindow:docWindow
        modalDelegate:self
       didEndSelector:@selector(my_blockSheetDidEnd:returnCode:contextInfo:)
          contextInfo:Block_copy((__bridge void *)block)];
}


- (void)my_blockSheetDidEnd:(NSWindow *)sheet
                 returnCode:(NSInteger)returnCode
                contextInfo:(void *)contextInfo
{
    void (^block)(NSInteger) = (__bridge_transfer id)contextInfo;
    block(returnCode);
}

In the first method,

Block_copy((__bridge void *)block)

means the following: cast block to void * using a __bridge cast. This cast tells ARC that it shouldn’t manage the ownership of the operand, so ARC won’t touch block memory-management-wise. On the other hand, Block_copy() does copy the block so you need to balance that copy with a release later on.

In the second method,

void (^block)(NSInteger) = (__bridge_transfer id)contextInfo;

means the following: cast contextInfo to id (the generic object type in Objective-C) with a __bridge_transfer cast. This cast tells ARC that it should release contextInfo. Since the block variable is __strong (the default qualifier), the Block is retained and, at the end of the method, it is finally released. The end result is that block gets released at the end of the method, which is the expected behaviour.


Alternatively, you could compile that category with -fno-objc-arc. Xcode allows files in the same project to build with or without ARC enabled.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!