我正在寻找一种 shorter/better 方法来从我的核心数据应用程序中获取第一个对象和 NSSet

I'm looking for a shorter/better way to get the first object from and NSSet in my Core Data app

目前我有这个代码:

if let myPhoneNumbers = person.phoneNumbers?.allObjects as? [PhoneNumber] {
        for myPhoneNumber in myPhoneNumbers {
        mainPhoneNumber = myPhoneNumber.number
        break
    }
}

这是正确的编码方式吗?我知道 NSSet 是无序的,可能是它没有自己的 .first 实现的原因,例如:

person.phoneNumbers.first

但我认为我的代码不是最优雅的代码,可能不合适 Swift 代码。

我不知道您为什么想要获取集合中的任意 "first" 元素,但您可以:

let first = (person.phoneNumbers?.allObjects as? [PhoneNumber])?.first

这将给出 more/less 个随机结果。以下是我的建议:

  • 将 phone 个数字存储在数组中,以便保留用户对 phone 个数字的排序。
  • 我认为由用户来确定什么构成主号码会好得多。也许在 Person.
  • 中存储对 "main" PhoneNumber 对象的引用

在您的代码中,myPhoneNumbers 是一个数组,因此您可以使用 myPhoneNumbers.first 而不是循环。

if let myPhoneNumbers = person.phoneNumbers?.allObjects as? [PhoneNumber] {
    mainPhoneNumber = myPhoneNumbers.first
}

但是,正如已经指出的那样,您应该对您的集合强加某种顺序,以便执行此代码的结果对于任何给定的集合都是相同的。武断的结果通常是不好的。

既然你提到你正在使用 Core Data,我建议在你的 Person 实体上添加一个方便的 属性 到 return phone 数字作为排序数组。

如果您的实体看起来像这样...

class PhoneNumber: NSManagedObject {
    @NSManaged var number: String
}

class PersonEntity: NSManagedObject {
    @NSManaged var phoneNumbers: NSSet?
}

...你可以像这样创造一个便利 属性:

class PersonEntity: NSManagedObject {

    @NSManaged var phoneNumbers: NSSet?

    // Arrays are often easier to work with than sets, 
    //  so provide a convenience property that returns
    //  phone numbers sorted
    var phoneNumbersArray: [PhoneNumber] {
        get {
            if let phoneNumbers = phoneNumbers {
                return (phoneNumbers.allObjects as! [PhoneNumber]).sorted() {
                    // here, sorting by phone number, but
                    // you can sort on whatever you want
                    .number > [=12=].number
                }
            }
            // return empty array if set is nil
            return [PhoneNumber]()
        }
    }
}

最后,一行代码得到第一个数字,如下所示:

mainPhoneNumber = person.phoneNumbersArray.first

我喜欢将这种类型的便利数组 属性 添加到我的所有具有集合的实体中。在我看来,数组更容易使用。这里我选择return一个空数组而不是一个nil数组,当集合为nil时。如果您可以处理 nil 和空 phone 设置相同,则此方法有效。

另请注意,如果 phoneNumbersArray 为空,则 .first return 为零。