Comment créer un tableau de classe dans Swift

dans l'objectif c, je pourrais créer un tableau de classe et l'utiliser dans une méthode

NSArray *classes = @[[NSAttributedString class]];
NSArray *items = [pasteboard readObjectsForClasses:classes
                                           options:nil];

cependant, swift n'a pas de fonction de" classe". Retourner un Métatype pour une classe entraîne une erreur

    let aClass : AnyClass!  = NSAttributedString.self
    //or let aClass:AnyClass! = NSAttributedString.classForArchiver()

    let pasteboard = NSPasteboard.generalPasteboard()

    let classes = [aClass]

    let objects = pasteboard.readObjectsForClasses(classes, options: nil)

la dernière ligne se traduit par "erreur fatale: l'élément du réseau ne peut pas être relié à L'objectif-C "

comment créer un tableau de classe dans Swift?

21
demandé sur Zag 2014-06-12 03:59:17

3 réponses

apparemment, cela a été fixé dans la Bêta 3 de sorte qu'il n'y a plus besoin de solutions de rechange

j'ai trouvé un pur Swift hack:

func classFromType<T: NSObject>(type: T.Type) -> AnyObject! {
    return T.valueForKey("self") //ask for class indirectly...
}

var clazz: AnyObject = classFromType(NSAttributedString.self)
var classes = [clazz]

précédente réponse

Je n'ai pas pu obtenir L'instance Class par aucun moyen dans Swift. Il semble qu'il ne puisse pas être converti directement à partir de AnyClass . Par exemple, ce qui suit n'est pas possible ( runtime)

var classes: NSMutableArray = []
classes.addObject(NSClassFromString(NSAttributedString.className()))

donc je suis entré dans Obj-C et défini un simple NSMutableArray catégorie:

@implementation NSMutableArray (ClassArray)

- (void)addClassByName:(NSString *)className {
    [self addObject:NSClassFromString(className)];
}

@end

puis

var classes: NSMutableArray = []
classes.addClassByName(NSAttributedString.className())

fonctionne, mais c'est un peu un hack.

13
répondu Sulthan 2014-07-09 09:17:06

dans Swift 2.0 vous pouvez utiliser

let urls = _pasteboard.readObjectsForClasses([NSURL.self, NSString.self], options: nil)

comme <ClassName>.self retourne AnyClass valeur

2
répondu medvedNick 2015-11-10 11:19:19

il semble plutôt comme si le pont de tableau fonctionne sur N'importe Quelobject, mais votre aClass n'est pas N'importe Quelobject, c'est N'importe quelle classe! - la trace de la pile à l'erreur dit

Swift._arrayBridgeToObjectiveC <A, B>(Swift.Array<A>) -> Swift.Array<B> ()

et l'assembleur avant de s'arrêter semble comme s'ils sont délibérément piéger sur elle n'étant aucun objet.

changer votre code en

var classAsAnyObject : AnyObject = aClass as AnyObject
//var classes = [aClass]
var classes = [classAsAnyObject]

provoque un crash immédiat dans objc_retain, comme le fait

var array = NSArray(object:aClass)

donc je suppose que c'est quelque chose à voir avec l'ARC et les classes.

la manipulation des Classes comme objets eux-mêmes dans Swift semble pour le moins obscure.

cela ne répond pas à la vraie question (comment créer un tableau de classes), mais pour l'application que vous avez utilisée comme exemple, vous pourriez La contourner en faisant quelque chose comme:

    var pasteboard = NSPasteboard.generalPasteboard()
    let allObjects = pasteboard.pasteboardItems
    println("allObjects=\(allObjects)")
    for item : AnyObject in allObjects {
        println("item=\(object_getClassName(item))")
        if let pbi = item as? NSPasteboardItem {
            println("item.types=\(pbi.types)")
            let str = pbi.stringForType("public.utf8-plain-text")
            println("item as string \(str)")
        }
    }
1
répondu Grimxn 2014-06-12 10:10:03