【问题标题】:Calling Core-Foundation methods from Swift从 Swift 调用 Core-Foundation 方法
【发布时间】:2014-11-03 19:08:00
【问题描述】:

我熟悉 Obj-c 并熟悉 Swift,但我在 Swift 非常严格的类型检查方面遇到了可怕的问题。举个例子,我想做的就是在下面的 Obj-c 中转换例程:

- (void)receiveIncomingConnectionNotification:(NSNotification *)notification {
    NSDictionary *userInfo = [notification userInfo];
    NSFileHandle *incomingFileHandle = [userInfo objectForKey:NSFileHandleNotificationFileHandleItem];

    if (incomingFileHandle) {
        CFDictionaryAddValue(
            incomingRequests,
            (__bridge const void *)(incomingFileHandle),
            (__bridge const void *)((__bridge id)CFHTTPMessageCreateEmpty(kCFAllocatorDefault, TRUE)));
    }
}

在 Swift 中这样做:

func receiveIncomingConnectionNotification(notification: NSNotification) {
    let userInfo: NSDictionary = notification.userInfo!
    let incomingFileHandle: NSFileHandle? = userInfo.objectForKey(NSFileHandleNotificationFileHandleItem) as? NSFileHandle
    if (incomingFileHandle != nil) {
        CFDictionaryAddValue(self.incomingRequests as CFMutableDictionaryRef, incomingFileHandle, CFHTTPMessageCreateEmpty(kCFAllocatorDefault, true))
    }
}

但是 CFDictionaryAddValue 调用不断生成指向“Cannot convert the expression's type '(CFMutableDictionaryRef, NSFileHandle?, Unmanaged<CFHTTPMessage>!' to type BooleanLiteralConvertible!”的“真”参数的错误。

任何人都知道执行此操作的正确方法,或者 BooleanLiteralConvertible 是什么?

【问题讨论】:

  • incomingRequests 是如何声明的?

标签: swift core-foundation


【解决方案1】:

如果你一次只考虑一个参数会更清楚:

let m = CFHTTPMessageCreateEmpty(kCFAllocatorDefault, 1).takeRetainedValue()
let f = incomingFileHandle!
let d = self.incomingRequests as CFMutableDictionaryRef
CFDictionaryAddValue(d, unsafeAddressOf(f), unsafeAddressOf(m))
  • C 布尔值必须表示为数字。

  • CFHTTPMessageCreateEmpty 需要内存管理,因为它作为非托管返回。

  • 您的incomingFileHandle 是可选的;它需要展开。

  • CFDictionaryAddValue 需要不安全的地址 (UnsafePointer)。

【讨论】:

  • 谢谢,帮了大忙!但是,如果您不介意,当 CFDictionary 设置为保留添加到其中的值时,为什么我必须包含“takeRetainedValue()”?另外,我的印象是未包装的变量是地址?最后,为什么是“unsafeAddressOf”?指向实际对象有什么不安全的地方?
  • 你只要跟着你的鼻子走,如果你明白我的意思。例如,看一下 CFDictionaryAddValue 的 Swift 声明:func CFDictionaryAddValue(theDict: CFMutableDictionary!, key: UnsafePointer<Void>, value: UnsafePointer<Void>)。好吧,正如你所说,Swift 是严格的,所以除非我们实际提供 UnsafePointer<Void> 对象,否则它不会让我们通过这一点,而且只有一种方法可以获取这些对象,即调用 unsafeAddressOf。这与您的 const void * 演员完全平行。
  • 至于takeRetainedValue(),我已经解释过了。 CFHTTPMessageCreateEmpty 返回一个 Unmanaged,在你告诉 Swift 如何管理它之前,你不能在 Swift 中对 Unmanaged 做任何事情。这与您的 bridge 演员完全平行。该方法名称中带有“Create”,因此保留;你需要告诉 Swift,否则你会泄露它。 (我注意到你在 Objective-C 中没有做到这一点。)
  • 完美!再次感谢您的解释。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-15
  • 1970-01-01
  • 2018-02-18
  • 2018-04-04
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多