当前位置: 首页 > 面试题库 >

使用Swift中的C API

顾超
2023-03-14
问题内容

我正在尝试跟踪网络状态。我浏览了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方法。我UTF8String在Objective-
C中找不到与属性完全相同的Swift
。但是,有一个叫做属性utf8String类型。根据文档,

您可以通过迭代其utf8属性来访问字符串的UTF-8表示形式。此属性的类型为String.UTF8View,它是无符号8位(UInt8)值的集合,每个值对应于字符串的UTF-8表示形式的每个字节:

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

2.SCNetworkReachabilitySetCallback的回调函数。

该函数的第二个参数要求类型为SCNetworkReachabilityCallBack。我深入到源文件中,发现它实际上是一个typealias

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

我是这样定义的。

let reachabilityCallBack: SCNetworkReachabilityCallBack = {

}()

但是我收到错误消息 :期望在闭包中返回’SCNetworkReachabilityCallBack’的闭包中缺少返回,
当您在该类型别名中可以清楚地看到它返回时Void

这是错误的方法吗?

这些是我面临的问题。我来这里已经好几个小时了,没有运气,所以我非常感谢您的帮助。

谢谢。


问题答案:

您的第一个问题可以用解决

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

在闭包内部,$0是一个指向NUL终止的String的UTF-8表示形式的指针。

更新: 正如Nate Cook在现在删除的答案中以及在这里所说的那样,您实际上可以将Swift字符串传递给UnsafePointer<UInt8>直接采用以下形式的函数:

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

不幸的是(据我所知)目前还没有解决您的第二个问题的方法。
SCNetworkReachabilitySetCallback需要将指向C函数的指针作为第二个参数,并且目前没有方法可以传递Swift函数或闭包。请注意,该文档SCNetworkReachabilityCallBack
仅显示了Objective-C,而没有显示Swift。

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)


 类似资料:
  • 本文向大家介绍Swift使用Objective-C代码中的Swift类,包括了Swift使用Objective-C代码中的Swift类的使用技巧和注意事项,需要的朋友参考一下 示例 在同一模块中 在名为“ MyModule ”的模块内,Xcode生成一个名为的标头,该标头MyModule-Swift.h将公共Swift类公开给Objective-C。导入此标头以使用Swift类: 相关的构建设置:

  • 问题内容: 因此,我正在使用雷·温德利奇(Ray Wenderlich)的教程编写的一本名为iOS游戏的书,并尝试利用那里找到的一些Objective- C代码来对游戏中角色的加速度计进行控制。我想使用Swift而不是Objective-C。尝试创建表示3D矢量的GLKVector3类型的var时遇到问题。当我输入: 我收到以下错误: 使用模块GLKVector3作为类型。 我的GLKit的快速文

  • 问题内容: 我正在努力在现场实施横幅广告,但它总是报告“线程1:EXC_BREAKPOINT(代码= EXC_ARM_BREAKPOINT,子代码= Oxdefe),程序停止运行。我在有关iAd()的另一个问题中引用了T先生的回答。 Swift-ADBannerView“),但仍然无法实现。 代码如下: 我在Main.storyboard中创建了一个ADBannerView,并将其与@IBOutl

  • 问题内容: 我的 TapCell1.swift 这是习惯 我的 ViewController.swift 正确设置了其所有数据源和代理。但是未显示我的自定义单元格。 问题是我的自定义单元格未显示。请提出我做错的任何事情。 注意:这是我的代码 我的文件下载链接 问题答案: 我终于做到了。 对于TapCell1.swift 对于NextViewController.swift 我的工作代码链接:自定义

  • 问题内容: 在我的项目中,我在UICollectionViewCell中创建了Cell 由于未捕获的异常,其出现了“错误终止”应用程序 代码如下。 GalleryCell.swift 我在My ViewController中使用了该单元格: 代码如下: NextViewController.swift } 我的问题是我遇到以下错误: 问题答案: 我加入以下两行下: 问题是我没有注册笔尖。现在我正在

  • 问题内容: 我想在Swift 3.0中使用生成随机字节。这是我在Swift 2.2中所做的 在Swift 3中,我尝试这样做,因为我知道unsafemutablebytes的概念现在有所不同,但是它不允许我返回。如果我评论退货部分,它仍然会说 有谁知道如何解决这一问题? 谢谢 问题答案: 您已经关闭了,但是内部的封闭是从封闭而不是外部函数返回的。因此,仅应在闭包中调用该方法,并将结果传递回去。 对