0

在 swift 2 中,我有一个用于处理扩展属性的 NSURL 扩展,其中包括:

func setAttribute(name: String, value: String) {
    let data = value.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    setxattr(self.path!, name, data.bytes, data.length, 0, 0)
}

func getAttribute(name: String) -> String? {
    let length = getxattr(self.path!, name, nil, 0, 0, 0)
    if length == -1 {
        return nil
    }
    let bytes = malloc(length)
    if getxattr(self.path!, name, bytes, length, 0, 0) == -1 {
        return nil
    }
    return (String(data: NSData(bytes: bytes, length: length),
        encoding: NSUTF8StringEncoding))
}

func attributes() -> [String : String]? {
    let length = listxattr(self.path!, nil, 0, 0)
    if length == -1 {
        return nil
    }
    let bytes = UnsafeMutablePointer<Int8>(malloc(length))
    if listxattr(self.path!, bytes, length, 0) == -1 {
        return nil
    }
    if var names = NSString(bytes: bytes, length: length,
        encoding: NSUTF8StringEncoding)?.componentsSeparatedByString("\0") {
            names.removeLast()
            var attributes: [String : String] = [:]
            for name in names {
                attributes[name] = getAttribute(name)!
            }
            return attributes
    }
    return nil
}

现在我正在尝试将其转换为 Swift 3,但 Xcode 一直在抱怨。

我把前两个函数改成了这个,但我不确定我做得对:

func setAttribute(_ name: String, value: String) {
    let data = value.data(using: String.Encoding.utf8, allowLossyConversion: false)!
    setxattr(self.path, name, (data as NSData).bytes, data.count, 0, 0)
}

func getAttribute(_ name: String) -> String? {
    let length = getxattr(self.path, name, nil, 0, 0, 0)
    if length < 0 {
        return nil
    }
    guard let bytes = malloc(length),
        getxattr(self.path, name, bytes, length, 0, 0) >= 0 else {
            return nil
    }
    if getxattr(self.path, name, bytes, length, 0, 0) < 0 {
        return nil
    }
    return (String(data: Data(bytes: bytes, count: length),
        encoding: String.Encoding.utf8))
}

我必须在第一个函数中投射Data到那里吗?NSData有没有更好的方法来解决这一切?

最后一个函数被 Xcode 转换为:

func attributes() -> [String : String]? {
    let length = listxattr(self.path, nil, 0, 0)
    if length == -1 {
        return nil
    }
    let bytes = UnsafeMutablePointer<Int8>(malloc(length))
    if listxattr(self.path, bytes, length, 0) == -1 {
        return nil
    }
    if var names = NSString(bytes: bytes, length: length,
        encoding: String.Encoding.utf8)?.components(separatedBy: "\0") {
            names.removeLast()
            var attributes: [String : String] = [:]
            for name in names {
                attributes[name] = getAttribute(name)!
            }
            return attributes
    }
    return nil
}

但我明白了

无法使用类型为“(UnsafeMutableRawPointer!)”的参数列表调用类型“UnsafeMutablePointer”的初始化程序

而且我不知道该怎么办。Xcode 的转换也坚持NSString. 我不能在那里使用String吗?

如果还不是很明显,我不知道我在做什么,哈哈。我的原始代码基于,但我无法理解所有这些malloclength东西是如何bytes工作的。我尝试阅读文档DataUnsafeMutablePointer,但并没有太大帮助。

如果有人可以帮助我转换此代码,我将不胜感激,但即使只是为我指出正确的方向以理解所有这些,也已经是一个巨大的帮助。我不知道还能去哪里看,所有这些东西对我来说似乎真的很神秘。我最近发现的少数几个来源假设我知道很多我不知道的东西,我什至不知道要寻找什么。

谢谢!

4

0 回答 0