2016-04-15 19 views
3

Wie Sie ein Array von Protokoll-Instanzen in AnyObject s downcast? Ich habe einige der sinnvolleren Ideen im folgenden Codebeispiel ausprobiert.Swift AnyObject - Down-Casting eines Arrays von Protokollen zu [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") 

Für das, was es wert ist, kommt setArray(_ anArray: [AnyObject]?, forKey aKey: String) Methodensignatur von NSUbiquitousKeyValueStore Klasse von Apple, so kann ich nicht wirklich neu gestalten Art sicher zu sein.

+0

Wenn ein Objekt "AnyObject" entspricht, aber sein Typ ist ausgeprägter, muss das Objekt nicht in "AnyObject" umgewandelt werden, um einer Methodensignatur zu entsprechen. In Ihrem Fall - wie Eric in seiner Antwort erwähnt - besteht das Problem darin, dass "NSUbiquitousKeyValueStore" nur Typen unterstützt, die mit der Eigenschaftsliste kompatibel sind. – vadian

Antwort

4

Es ist weniger als perfekt, aber es funktioniert, wenn das Protokoll und Klasse sind beide @objc (und die Klasse Subklassen 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

Danke! Der Schlüssel hier ist, dass 'AnyObject' mit '@ objc' versehen ist, während mein Protokoll _not_ ist. Daher macht es Sinn, dass es nicht möglich ist zu casten. – edelaney05

0

Dies ist nicht wirklich beantworte deine Frage direkt, aber ich denke nicht, dass dies so funktionieren wird, wie du es erwartest.

Aus der Dokumentation für NSUbiquitousKeyValueStore setArray:

Ein Array, dessen Inhalt in einer Eigenschaftsliste Format gespeichert werden. Mit anderen Worten müssen die Objekte in der Anordnung der Typen sein NSNumber, NSString, NSDate, NSData, NSArray oder NSDictionary. Die Gesamtgröße (in Byte) des Arrays und seines Inhalts darf die Größenbeschränkungen pro Schlüssel nicht überschreiten.

Sie versuchen, Daten in das ist nicht einer der oben genannten und ich vermute, Sie werden in Probleme stoßen.

So etwas wie dies funktionieren würde:

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") 

Oder Sie könnten serialisiert Swift eine andere Art und Weise Objekte, um sie in einem der unterstützten Klassen zu erhalten.

Verwandte Themen