Почему Set не является типом списка свойств? - PullRequest
0 голосов
/ 21 февраля 2019

Я пытался сохранить тип Set<String> в пользовательских настройках по умолчанию и получил сообщение об ошибке «Попытка установить объект, не являющийся списком свойств».

, что заставило меня задуматься, почему Set не являетсятип списка свойств?

Почему допускаются массивы и словари, но не наборы?

Редактировать: Мне известны другие способы хранения моих данных.Мне просто интересно, есть ли известная или предполагаемая причина, по которой Apple решила, что наборы не являются типами списков свойств.

Это потому, что в наборах нет таких ключей, как массивы (индекс) и словари (ключ)?Это потому, что множества неупорядочены?Но словари тоже неупорядочены ..

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Списки свойств представляют данные, а не детали реализации.Массив - это упорядоченный список.Диктовка - это отображение строковых ключей на значения.Что такое «набор»?Это не означает ничего особенного в простых текстовых данных.Если в списке не может быть дубликатов, не пишите дубликаты.Если он неупорядочен, игнорируйте порядок.Все, что связано с множеством, связано с манипулированием данными.(Какое поведение вы ожидаете от plist-набора, который на самом деле имеет дублирующиеся элементы? Будет ли он недействительным? Если нет, то как это не просто массив?)

Списки свойствне общий инструмент сериализации дерева объектов.Вот для чего NSCoder.Они в первую очередь предназначены для удобной для записи конфигурации, такой как Info.plist, и могут быть проанализированы на любом языке.NSUserDefaults также не является хранилищем данных общего назначения (если бы оно было, оно называлось бы «NSApplicationDataStore» или что-то в этом роде).Он был разработан для хранения пользовательских данных конфигурации таким образом, чтобы пользователи могли редактировать их вручную.

Исходный (NeXTSTEP) формат был гораздо проще набирать:

SomeKey = {
    MyFirstProperty = ("here's", "a", "list");
    SomeOtherThing = "I'm a string";
};

Apple перешла на XMLс OS X, что делает его гораздо сложнее печатать, но основной подход был тот же.(В первые дни OS X Apple предприняла много шагов для интеграции Java в систему, в том числе больше полагаясь на XML, включая формальные DTD . Оглядываясь назад, многие из этих шагов, вероятно, были неудачными, но онив то время имел смысл.)

Списки решают те же проблемы, что и JSON.Они предоставляют минимальный набор типов, которые необходимы для кодирования необработанных данных, а не структуры данных для реализации алгоритмов.

Я не говорю, что списки были созданы на основе некоторых математических принципов.Если бы NSSet был невероятно распространенным типом данных конфигурации, я уверен, что он нашел бы свой путь в этот формат.Но они просто не были изобретены как универсальный способ сохранения произвольных данных приложения, равно как и NSUserDefaults.

0 голосов
/ 21 февраля 2019

Вам нужно сначала заархивировать свой набор, чтобы сделать его Data объектом.Только тогда вы можете сохранить эти данные по умолчанию.

Примерно так:

let sets: Set<String> = Set(arrayLiteral: "a","b","c")
let encodedData = NSKeyedArchiver.archivedData(withRootObject: sets)
UserDefaults.standard.setValue(encodedData, forKeyPath: "test")

И затем, чтобы разархивировать ваши данные, сделайте это так (и тогда вы сможете вернуть свой набор)

if let data = UserDefaults.standard.data(forKey: "test"),
    let set = NSKeyedUnarchiver.unarchiveObject(with: data) as? Set<String> {
    print(set)
}

Что касается причины, по которой вы не можете сохранить свой набор без архивирования, вот что говорит Apple:

Объектом по умолчанию должен быть список свойств, то естьэкземпляр (или для коллекций, комбинация экземпляров) NSData, NSString, NSNumber, NSDate, NSArray или NSDictionary.Если вы хотите сохранить какой-либо другой тип объекта, вам, как правило, следует архивировать его, чтобы создать экземпляр NSData.

https://developer.apple.com/documentation/foundation/userdefaults

Как вы можете видеть, если вы преобразуете свойустановите Array или Data, вам будет удобно сохранить его на UserDefaults.

...