gpt4 book ai didi

ios - 在 Swift 中使用 C API

转载 作者:搜寻专家 更新时间:2023-10-31 08:13:26 25 4
gpt4 key购买 nike

我正在尝试跟踪网络状态。我浏览了 FXReachability 的代码.具体有以下方法。

- (void)setHost:(NSString *)host
{
if (host != _host)
{
if (_reachability)
{
SCNetworkReachabilityUnscheduleFromRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
CFRelease(_reachability);
}
_host = [host copy];
_status = FXReachabilityStatusUnknown;
_reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [_host UTF8String]);
SCNetworkReachabilityContext context = { 0, ( __bridge void *)self, NULL, NULL, NULL };
SCNetworkReachabilitySetCallback(_reachability, ONEReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}
}

它的作用是不断检查与指定主机的连接。我正在尝试将此方法转换为 Swift,但遇到了一些问题。

<强>1。将主机字符串转换为 UTF8。

我必须将主机字符串转换为 UTF8 并将其传递到 SCNetworkReachabilityCreateWithName方法。我在 Objective-C 中找不到与 UTF8String 属性完全相同的 Swift。但是 String 类型有一个名为 utf8 的属性。根据documentation ,

You can access a UTF-8 representation of a String by iterating over its utf8 property. This property is of type String.UTF8View, which is a collection of unsigned 8-bit (UInt8) values, one for each byte in the string’s UTF-8 representation:

如何获得字符串的完整 UTF8 表示而不是无符号 8 位 (UInt8) 值的集合?


<强>2。 SCNetworkReachabilitySetCallback 的回调函数.

此函数的第二个参数需要 SCNetworkReachabilityCallBack 类型的内容。我深入研究了源文件,发现它实际上是一个 typealias

typealias SCNetworkReachabilityCallBack = CFunctionPointer<((SCNetworkReachability!, SCNetworkReachabilityFlags, UnsafeMutablePointer<Void>) -> Void)>

我是这样定义的

let reachabilityCallBack: SCNetworkReachabilityCallBack = {

}()

但我收到错误Missing return in a closure expected to return 'SCNetworkReachabilityCallBack',当在该类型别名中时您可以清楚地看到它返回 Void

这是错误的做法吗?


这些是我面临的问题。我已经在这几个小时了,但没有运气,所以我真的很感激任何帮助。

谢谢。

最佳答案

你的第一个问题可以用

解决
let reachability = host.withCString {
SCNetworkReachabilityCreateWithName(nil, $0).takeRetainedValue()
}

在封闭内部,$0是指向以 NUL 结尾的 UTF-8 表示的指针字符串。

更新:作为Nate Cook说在现在已删除的答案,还有 here ,您实际上可以将 Swift 字符串传递给采用 UnsafePointer<UInt8> 的函数直接:

let reachability = SCNetworkReachabilityCreateWithName(nil, host).takeRetainedValue()

不幸的是(据我所知)目前没有解决您的第二个问题的方法。 SCNetworkReachabilitySetCallback期望一个指向 C 函数的指针作为第二个参数,目前还没有传递 Swift 函数或闭包的方法。请注意 SCNetworkReachabilityCallBack 的文档仅显示 Objective-C 但不显示 Swift。

另见 Does Swift not work with function pointers? .


Swift 2 更新:现在可以传递 Swift 闭包到采用函数指针参数的 C 函数。还 SCNetworkReachabilityCreateWithName()不再返回非托管对象:

let host = "google.com"
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let reachability = SCNetworkReachabilityCreateWithName(nil, host)!

SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in
print(flags)
}, &context)

SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)

Swift 3 (Xcode 8) 更新:

let host = "google.com"
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let reachability = SCNetworkReachabilityCreateWithName(nil, host)!

SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in
print(flags)
}, &context)

SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(),
CFRunLoopMode.commonModes.rawValue)

关于ios - 在 Swift 中使用 C API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27142263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com