【问题标题】:ObjC casting a block with toll-free-bridged typesObjC 使用免费桥接类型铸造一个块
【发布时间】:2015-10-28 17:55:38
【问题描述】:

是否可以将采用具有免费桥接等效物的 Objective-C 类型的块直接传递到期望具有 C 类型的块的方法中?

具体例子

我根据可用性包装了 AddressBook 和 Contacts API,并且框架包含两种方法,它们的所有意图和目的都是相同的。考虑完成块参数:

CNContactStore- (void)requestAccessForEntityType:(CNEntityType)entityType completionHandler:(void (^)(BOOL granted, NSError *error))completionHandler

AddressBookvoid ABAddressBookRequestAccessWithCompletion ( ABAddressBookRef addressBook, void(^)(bool granted, CFErrorRef error) completion );

我有一个void (^)(BOOL granted, NSError *error) 类型的块,如果我可以将它传递给ABAddressBookRequestAccessWithCompletion(...),那就太好了。我知道我可以将我的“objc”块包装在一个将“C 类型”作为参数的块中,但是当类型是免费桥接时这样做感觉毫无意义。

具体问题

有没有办法将void (^)(BOOL granted, NSError *error 类型的对象转换为void(^)(bool granted, CFErrorRef error) 类型?如果可以,语法是什么? ARC 环境中所有权的含义是什么?

【问题讨论】:

    标签: objective-c automatic-ref-counting toll-free-bridging


    【解决方案1】:

    只需投射方块。

    作为一个非常粗略的例子:

    typedef void(^InternalBlock)(bool granted, CFErrorRef error);
    
    - (void)requestAccess:(void (^)(BOOL, NSError *))completion {
    
        if ([CNContactStore class]) {
            [contactStore requestAccessForEntityType:CNEntityTypeContacts completionHandler:completion];
        } else {
            ABAddressBookRequestAccessWithCompletion(addressBook, (InternalBlock)completion);
        }
    
    }
    

    【讨论】:

    • 我什至从未考虑过进行非桥接转换,因为我害怕底层的内存管理。 “在 ARC 环境中所有权的含义是什么?”我是不是把问题复杂化了。我猜所有块都是 ObjC 对象(读取:id),无论它是否包含 C 或 ObjC 类型,所以内存管理无关紧要。
    猜你喜欢
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 2010-10-22
    • 2014-12-26
    • 1970-01-01
    相关资源
    最近更新 更多