beginSheet:block替代用ARC? [英] beginSheet: block alternative with ARC?

查看:227
本文介绍了beginSheet:block替代用ARC?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Mike Ash创建了一个使用块的示例处理回调从表,这似乎很不错。这反过来被更新以处理用户Enchilada在另一个SO问题的垃圾收集在 beginSheet:block alternative?,见下文

Mike Ash created an example of using blocks to handle callbacks from sheets, which seems very nice. This was in turn updated to work with garbage collection by user Enchilada in another SO question at beginSheet: block alternative?, see below.

@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协同工作?

While enabling GC, this does not work with Automatic Reference Counting (ARC). Myself, being a beginner at both ARC and blocks, can't get it to work. How should I modify the code to get it to work with ARC?

我得到的Block_release()东西需要去,但我不能通过编译错误铸造'void  *'到'void& )

I get that the Block_release() stuff needs to go, but I can't get past the compile errors about casting 'void *' to 'void (^)(NSInteger)' being disallowed with ARC.

推荐答案

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

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.

你可以解决ARC使用下面的代码:

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

在第一种方法中,

Block_copy((__bridge void *)block)

表示以下内容:使用 __ bridge 更改为 void * c> cast。这个转换告诉ARC它不应该管理操作数的所有权,所以ARC不会触及内存管理方面的 block 。另一方面, Block_copy()会复制该块,因此您需要稍后将该副本与发行版进行平衡。

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.

在第二种方法中,

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

表示以下内容:cast contextInfo code> __ bridge_transfer cast。code> id (Objective-C中的通用对象类型)这个转换告诉ARC应该释放 contextInfo 。因为变量是__strong(默认限定符),所以块被保留,并且在方法结束时,它最终被释放。最终结果是 block 在方法结束时被释放,这是预期的行为。

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.

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

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

这篇关于beginSheet:block替代用ARC?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆