objective-c – beginSheet:使用ARC阻止替代方案?

前端之家收集整理的这篇文章主要介绍了objective-c – beginSheet:使用ARC阻止替代方案?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Mike Ash创建了一个从表单中使用 blocks to handle callbacks的示例,这看起来非常好.这又被更新为用户Enchilada在 beginSheet: block alternative?的另一个SO问题中进行垃圾收集,见下文.
@implementation NSApplication (SheetAdditions)

- (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(block)];
}

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

@end

启用GC时,这不适用于自动引用计数(ARC).我自己,作为ARC和街区的初学者,都无法让它发挥作用.我应该如何修改代码以使其与ARC一起使用?

我知道Block_release()的东西需要去,但我无法通过关于使用ARC禁止将’void *’转换为’void(^)(NSInteger)’的编译错误.

解决方法

ARC不喜欢转换为void *,这是Block_ *函数期望的参数,因为ARC无法推断不可保留类型的所有权.您需要使用桥接转换来告诉ARC它应该如何管理所涉及对象的所有权,或者它根本不应该管理它们的所有权.

您可以使用以下代码解决ARC问题:

- (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);
}

在第一种方法中,

Block_copy((__bridge void *)block)

表示以下内容:使用__bridge强制转换将块转换为void *.这个演员告诉ARC,它不应该管理操作数的所有权,因此ARC不会触及块内存管理方式.另一方面,Block_copy()会复制块,因此您需要在稍后的版本中平衡该副本.

在第二种方法中,

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

表示以下内容:使用__bridge_transfer强制转换将contextInfo转换为id(Objective-C中的通用对象类型).这个演员告诉ARC它应该释放contextInfo.由于块变量是__strong(默认限定符),因此保留块,并且在方法结束时,它最终被释放.最终结果是在方法结束时释放块,这是预期的行为.

或者,您可以使用-fno-objc-arc编译该类别. Xcode允许在启用或不启用ARC的情况下构建同一项目中的文件.

猜你在找的C&C++相关文章