【问题标题】:Using sysctlbyname() from Swift从 Swift 使用 sysctlbyname()
【发布时间】:2014-10-17 11:48:46
【问题描述】:

我正在使用来自 this Gist 的代码来确定我的应用在哪个 iOS 设备(例如 iPhone5,1)上运行:

- (NSString *)platform
{
    size_t size;
    sysctlbyname("hw.machine", NULL, &size, NULL, 0);
    char *machine = malloc(size);
    sysctlbyname("hw.machine", machine, &size, NULL, 0);
    NSString *platform = [NSString stringWithUTF8String:machine];
    free(machine);
    return platform;
}

The Swift documentation 表示 C 数据类型得到很好的支持,但它没有说明 C 函数。有没有一种纯粹的 Swift 方法来检索机器标识符,还是我必须为此桥接到 Objective-C?

【问题讨论】:

    标签: ios swift objective-c cocoa-touch


    【解决方案1】:

    您可以在 Swift 中执行相同的操作(为简洁起见,省略了错误检查):

    func platform() -> String {
        var size : Int = 0 // as Ben Stahl noticed in his answer
        sysctlbyname("hw.machine", nil, &size, nil, 0)
        var machine = [CChar](count: size, repeatedValue: 0)
        sysctlbyname("hw.machine", &machine, &size, nil, 0)
        return String.fromCString(machine)!
    }
    

    Swift 3 更新:

    func platform() -> String {
        var size = 0
        sysctlbyname("hw.machine", nil, &size, nil, 0)
        var machine = [CChar](repeating: 0,  count: size)
        sysctlbyname("hw.machine", &machine, &size, nil, 0)
        return String(cString: machine)
    }
    

    【讨论】:

    • 好吧,我会被诅咒的。我想我应该先尝试一下。谢谢!
    • 你省略了哪些错误检查,应该在这个函数中添加?谢谢。
    • @EmilAdz: sysctlbyname() 有一个返回值,成功时为零,失败时为-1。
    • 那么如果方法失败返回-1,我应该怎么检查呢?
    • @EmilAdz:我不确定你要什么。如果系统调用失败,则将全局变量errno 设置为指示失败原因的整数。在这种情况下怎么做取决于你(返回默认值、返回 nil、中止程序……)——在这种特殊情况下,如果你传递有效参数,我认为sysctlbyname() 不会失败。为了完整起见,我只是提到了这一点。
    【解决方案2】:

    从 Swift 1.2 (Xcode 6.3 beta-2) 开始,@MartinR 的上述代码需要稍作修改。 sysctlbyname 第一个参数需要一个 CChar 数组(即 C 字符串),“size”参数需要一个 Int(而不是 Uint)。

    func platformModelString() -> String? {
        if let key = "hw.machine".cString(using: String.Encoding.utf8) {
            var size: Int = 0
            sysctlbyname(key, nil, &size, nil, 0)
            var machine = [CChar](repeating: 0, count: Int(size))
            sysctlbyname(key, &machine, &size, nil, 0)
            return String(cString: machine)
        }
        return nil
    }
    

    编辑:2017 年 1 月 4 日更新 Swift 3 语法

    【讨论】:

    • 您对 size 参数的类型是正确的。但是将 Swift 字符串传递给 UnsafePointer<Int8> 参数在 Swift 1.2 中仍然有效,编译器会自动转换。
    • 我想你在函数末尾多了一个},对吧?
    • @bdesham 是的,对额外的 } 感到抱歉...草率的复制粘贴工作。固定。
    猜你喜欢
    • 1970-01-01
    • 2015-11-17
    • 2020-06-13
    • 2021-09-30
    • 2012-12-20
    • 2016-07-03
    • 2011-10-22
    • 2014-11-10
    • 1970-01-01
    相关资源
    最近更新 更多