我正在努力让NSSortDescriptors在我的mac桌上工作 我在下面做了一个快速的概念证明,它仍然显示相同的错误:
错误ProofSortDescriptors [19446:1951711]无法设置 (contentViewController)用户定义的检查属性(NSWindow): [< _SwiftValue 0x60400007c180> valueForUndefinedKey:]:这个类是 密钥名称不符合密钥值编码。 (名称是。的名称 结构的属性
这可能与Swift 4桥接Objective C的方式有关吗?
很高兴能在Mac Swift上运行
这是我的尝试:
import Cocoa
struct Customer {
var name:String
var value:Int
}
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let cust1 = Customer(name: "bob", value: 100)
let cust2 = Customer(name: "cat", value: 200)
let cust3 = Customer(name: "dog", value: 300)
var custcol = [cust2, cust3, cust1]
let descrip = NSSortDescriptor(key: "name", ascending: true)
let sorted = (custcol as NSArray).sortedArray(using: [descrip])
var sortedCustomers = sorted as? [Customer]
print(sortedCustomers!)
}
}
答案 0 :(得分:2)
您不能使用普通NSSortDescriptor
和Swift struct
。
普通的NSSortDescriptor
&n; compareObject:toObject:
方法使用“键值编码”来访问对象的属性。键值编码仅适用于NSObject
的实例(包括NSObject
的子类的实例)。 Swift struct
不是NSObject
的子类(甚至根本不是类)。
由于您使用排序描述符是因为NSTableView
用于对行进行排序,因此最简单的解决方案就是将模型对象类型从struct
更改为{ {1}}子类class
。然后声明每个可排序的属性NSObject
。
答案 1 :(得分:1)
swift 4
要在swift 4中使用NSSortDescriptors对自定义类数组进行排序,您需要声明如下所示的类。
@objcMembers class Customer:NSObject {
var name:String!
var value:Int!
}
答案 2 :(得分:0)
除非您有特殊原因,否则应避免在Swift代码中使用Objective-C文件。在NSArray之间来回衔接是一个迹象,表明可能有更好的,更好的解决问题的方法。
let sortedCustomers = customers.sorted(by: { $0.name.compare($1.name) == .orderedAscending })
答案 3 :(得分:0)
以下是我需要的代码,无需更改NSSortDescriptor
即可实现此功能。要获得符合Customer
KVC标准,必须是class
从[{1}}派生的,并且任何符合KVC标准的属性都需要使用NSObject
进行标记。
@objc
执行此操作的更快捷方式是实现class Customer: NSObject {
@objc var name: String
var value: Int
init(name: String, value: Int) {
self.name = name
self.value = value
}
}
Comparable
或直接改变客户。
struct Customer {
var name: String
var value: Int
}
extension Customer: Comparable {
static func ==(lhs: Customer, rhs: Customer) -> Bool {
return lhs.name == rhs.name
}
static func <(lhs: Customer, rhs: Customer) -> Bool {
return lhs.name < rhs.name
}
}
class MyViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let cust1 = Customer(name: "bob", value: 100)
let cust2 = Customer(name: "cat", value: 200)
let cust3 = Customer(name: "dog", value: 300)
let custcol = [cust2, cust3, cust1]
let sortedCustomers = custcol.sorted()
print(sortedCustomers)
}
}