Swift AnyObject - приведение массива протоколов к [AnyObject]
Как вы понижаете массив экземпляров протокола в AnyObject
s? Я попробовал некоторые из более разумных идей в примере кода ниже.
protocol Nameable : class {
var name: String { get }
}
class Person: Nameable {
var name: String
init(name: String)
{
self.name = name
}
}
class Example {
func setArray(array: [AnyObject]?, forKey: String)
{
print("hello world")
}
}
var personOne = Person(name: "Evan")
var personTwo = Person(name: "Brian")
var array: [ Nameable ] = [ personOne, personTwo ]
var anotherArray = array.map({ $0 as AnyObject }) // OMG gross!
var yetAnotherArray = array as [ AnyObject ] // Nope.
var evenYetAnotherArray = array as? [ AnyObject ] // Nope.
var omgThisIsAnArray = Array<AnyObject>(array) // Ha ha, srsly. Nope.
var myExample = Example()
myExample.setArray(anotherArray, forKey: "Named")
Для чего это стоит, setArray(_ anArray: [AnyObject]?, forKey aKey: String)
Метод подписи исходит от Apple NSUbiquitousKeyValueStore
класс, так что я не могу по-настоящему изменить его, чтобы быть безопасным для типов.
2 ответа
Это менее чем идеально, но это работает, если протокол и класс оба @objc
(и подклассы класса NSObject
):
@objc protocol Nameable: class {
var name: String { get }
}
@objc class Person: NSObject, Nameable {
var name: String
init(name: String) {
self.name = name
}
}
...
var array: [Nameable] = [personOne, personTwo]
let array2 = array as [AnyObject] // ✓
Это не дает прямого ответа на ваш вопрос, но я не думаю, что это сработает так, как вы ожидаете.
Из документов для NSUbiquitousKeyValueStore setArray:
Массив, содержимое которого может быть сохранено в формате списка свойств. Другими словами, объекты в массиве должны иметь типы NSNumber, NSString, NSDate, NSData, NSArray или NSDictionary. Общий размер (в байтах) массива и его содержимого не должен превышать ограничения на размер ключа.
Вы пытаетесь вставить данные, которых нет в любом из вышеперечисленных, и я предполагаю, что у вас возникнут проблемы.
Примерно так будет работать:
import UIKit // For String<->NSString bridging
protocol Nameable : class {
var name: String { get }
}
class Person: Nameable {
var name: String
init(name: String)
{
self.name = name
}
}
class Example {
func setArray(array: [AnyObject]?, forKey: String)
{
print("hello world")
}
}
var personOne = Person(name: "Evan")
var personTwo = Person(name: "Brian")
var array: [ Nameable ] = [ personOne, personTwo ]
var nameArray = array.map({ $0.name }) // Now [String]
var myExample = Example()
myExample.setArray(nameArray, forKey: "Named")
Или вы можете сериализовать ваши объекты Swift другим способом, чтобы поместить их в один из поддерживаемых классов.