2016-04-15 2 views
3

Как вы сбрасываете массив экземпляров протокола в AnyObject? Я пробовал некоторые из более разумных идей в приведенном ниже примере кода.Swift AnyObject - Вниз приведение массива протоколов в [AnyObject]

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) сигнатура метода происходит от NSUbiquitousKeyValueStore класса Apple, так что я не могу перепроектировать, что типобезопасными.

+0

Если объект соответствует «AnyObject», но его тип более разный, нет необходимости бросать объект в «AnyObject», чтобы он соответствовал сигнатуре метода. В вашем случае - как упоминает Эрик в своем ответе - проблема в том, что 'NSUbiquitousKeyValueStore' поддерживает только типы, совместимые со списком свойств. – vadian

ответ

4

Это меньше, чем идеальный, но он работает, если протокол и класс как @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] // ✓ 
+1

Спасибо! Ключевым моментом здесь является то, что 'AnyObject' аннотируется с помощью' @ objc', тогда как мой протокол - _not_. Поэтому имеет смысл, что это невозможно сделать. – edelaney05

0

Это не очень ответьте на свой вопрос напрямую, но я не думаю, что это будет работать так, как вы ожидаете.

Из документов для 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 объекты какой-то другой способ, чтобы получить их в один из поддерживаемых классов.

Смежные вопросы