2

Можно ли передать блок, который принимает типы Objective-C, имеющие эквивалентные Toll-мосты, в метод, ожидающий блок с C-типами?ObjC литье блока с беспошлинными мостовыми типами

Конкретного пример

Я обертывание API, Addressbook и Контактов в зависимости от наличия и структуры содержат два метода, которые для всех намерений и целей, которые идентичны. Рассмотрим параметр завершения блокирования:

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

и

AddressBook» s void 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?

ответ

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

} 
+0

Я никогда даже не рассматривал делать немостиковый бросок, как я напуган о подстилающем управлении памятью. «Каковы последствия владения в среде ARC?» Я смущаю проблему. Я предполагаю, что все блоки являются объектами ObjC (read: id) независимо от того, содержит ли он C или ObjC-типы, поэтому управление памятью не имеет значения. –