将自定义对象的数组转换为Swift中的AnyObject

hkl*_*lel 3 nsdata nsarray ios swift

在我的应用程序中,我正在做这样的事情:

struct Record {
    var exampleData : String
}

class ExampleClass : UIViewController {
    let records = [Record]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let data = NSKeyedArchiver.archivedDataWithRootObject(self.records) as! NSData
    }

    ...

}
Run Code Online (Sandbox Code Playgroud)

但在最后一行viewDidLoad()我得到了这个错误:

参数类型'[Record]'不符合预期类型'AnyObject'

我怎样才能解决这个问题?谢谢.

Aar*_*ger 7

如果要保留struct,可以使用编码数据withUnsafePointer().这是一个例子,我改编自这个要点:

import UIKit

enum EncodingStructError: ErrorType {
    case InvalidSize
}

func encode<T>(var value: T) -> NSData {
    return withUnsafePointer(&value) { p in
        NSData(bytes: p, length: sizeofValue(value))
    }
}

func decode<T>(data: NSData) throws -> T {
    guard data.length == sizeof(T) else {
        throw EncodingStructError.InvalidSize
    }

    let pointer = UnsafeMutablePointer<T>.alloc(1)
    data.getBytes(pointer, length: data.length)

    return pointer.move()
}

enum Result<T> {
    case Success(T)
    case Failure
}
Run Code Online (Sandbox Code Playgroud)

我添加了一些错误处理并将方法标记为throws.这是一种可以使用它的方法,在do... catch块中:

var res: Result<String> = .Success("yeah")

var data = encode(res)

do {
    var decoded: Result<String> = try decode(data)

    switch decoded {
    case .Failure:
        "failure"
    case .Success(let v):
        "success: \(v)" // => "success: yeah"
    }
} catch {
    print(error)
}
Run Code Online (Sandbox Code Playgroud)

如果NSData长度与类型大小不匹配,我添加的错误处理将不会解码.如果您将数据写入磁盘,用户使用相同类型的不同大小的版本更新到较新版本的应用程序,然后读入数据,则通常会发生这种情况.

另请注意,sizeof()并且sizeofValue()可能会在不同的设备上返回不同的值,因此这不是在设备之间发送数据的好方法(NSJSONSerialization可能更好).