2016-10-19 41 views
1

我试图使用(现在是私有的)CTTelephonyCenterAddObserver C函数和CFNotificationCallback回调块来收听CoreTelephony通知。在Swift中使用CFNotificationCallback,或者在Swift中使用@convention(c)块

我的桥接报头(为extern私人C函数):

#include <CoreFoundation/CoreFoundation.h> 

#if __cplusplus 
extern "C" { 
#endif 

#pragma mark - API 

    /* This API is a mimic of CFNotificationCenter. */ 

    CFNotificationCenterRef CTTelephonyCenterGetDefault(); 
    void CTTelephonyCenterAddObserver(CFNotificationCenterRef center, const void *observer, CFNotificationCallback callBack, CFStringRef name, const void *object, CFNotificationSuspensionBehavior suspensionBehavior); 
    void CTTelephonyCenterRemoveObserver(CFNotificationCenterRef center, const void *observer, CFStringRef name, const void *object); 
    void CTTelephonyCenterRemoveEveryObserver(CFNotificationCenterRef center, const void *observer); 

    void CTIndicatorsGetSignalStrength(long int *raw, long int *graded, long int *bars); 

#pragma mark - Definitions 

    /* For use with the CoreTelephony notification system. */ 
    extern CFStringRef kCTIndicatorsSignalStrengthNotification; 

#if __cplusplus 
} 
#endif 

我的银行代码:

let callback: CFNotificationCallback = { (center: CFNotificationCenter?, observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) -> Void in 
    // ... 
} 

CTTelephonyCenterAddObserver(CTTelephonyCenterGetDefault().takeUnretainedValue(), nil, callback, kCTIndicatorsSignalStrengthNotification.takeUnretainedValue(), nil, .coalesce) 

但是,我不能让我的completion变量匹配的签名要求的CFNotificationCallback typealias。

Cannot convert value of type 
'(CFNotificationCenter?, UnsafeRawPointer?, CFString?, UnsafeRawPointer?, CFDictionary?) -> Void' 
to specified type 
'CFNotificationCallback' (aka '@convention(c) (Optional<CFNotificationCenter>, Optional<UnsafeMutableRawPointer>, Optional<CFNotificationName>, Optional<UnsafeRawPointer>, Optional<CFDictionary>) ->()') 

我怎样才能得到@convention(c)关闭在斯威夫特发挥很好?

+1

它不会编译,因为'observer'是一个'UnsafeMutableRawPointer',而不是'UnsafeRawPointer'。 –

回答

1

让编译器推断封闭的签名工作得很好:

let callback: CFNotificationCallback = { center, observer, name, object, info in 
    //works fine 
} 

试图指定在封闭的声明@convention(c)给出了一个错误:

let callback: CFNotificationCallback = { @convention(c) (center: CFNotificationCenter?, observer: UnsafeRawPointer?, name: CFString?, object: UnsafeRawPointer?, info: CFDictionary?) -> Void in 
    //Attribute can only be applied to types, not declarations. 
} 

好像发生了什么事情是,当你手动声明闭包的类型,它会强制编译器使用该确切类型。但这在技术上是封闭声明而不是类型声明,因此不允许使用@convention属性。当允许编译器推断闭包的类型(根据它存储的变量的类型)时,它也可以推断该属性。

+0

啊,所以,我是过分复杂的事情。谢谢! – JAL