2014-09-19 9 views
11

Eine einfache Swift-Klasse hat ein Feld vom Typ var Array. Wenn die Klasse Objective-C angepasst ist, die Halbbild-Typ wird als NSArray (unveränderliche) ausgesetzt, während es NSMutableArray sein sollte (veränderbare)Swift-Klassenfeld vom Typ var Array wird in unveränderliches NSArray anstelle von NSMutableArray konvertiert

class Categoryy: NSObject { 

    var items = Array<Item>() 

}

Die Categoryy SWIFT Klasse Objective-C in der Xcode generierten Header angepasst ist MODULE_NAME-swift.h Datei wie folgt:

SWIFT_CLASS("_TtC8waiterio9Categoryy") 
@interface Categoryy : NSObject 
@property (nonatomic, copy) NSArray * items; 
- (instancetype)init OBJC_DESIGNATED_INITIALIZER; 
@end

gibt es eine Möglichkeit für die var items: Array Feld auf ein veränderbares NSMutableArray in Objective-c umgewandelt werden?

+0

Sie sind nicht in der Lage den Header NSMutableArray zu ändern? – erdekhayser

+0

es ist keine machbare Lösung :(Der Xcode-generierte Header für Swift namens MODULE-swift.h wird gelöscht und neu erstellt von Xcode jedes Mal, wenn eine der Swift-Dateien eine Feld- oder Methodensignatur ändert. Sie können manuell den Typ ändern Felder von NSArray zu NSMutableArray, aber sobald Sie die Signatur einer schnellen Datei oder Methode ändern, gehen alle Ihre Änderungen verloren – Giorgio

+0

Haben Sie ein Radar auf diese Datei gelegt? –

Antwort

6

Das ist, weil items Eigenschaft ist eigentlich unveränderlich.

As you know, wegen der Art der struct basierte Implementierung von Array in Swift, folgenden Code hat keinen Einfluss auf cat.items.

let cat = Categoryy() 

var _items = cat.items 
_items.append(item) 

Stattdessen Sie dieses

cat.items.append(item) 

Auf der anderen Seite aufrufen müssen, in Objective-C, ist [cat.items addObject:item] genau die gleichen, wie folgend:

id _items = [cat items]; 
[_items addObject:item]; 

Das ist sehr ähnlich zu nicht funktionierendem Swift-Code.

Traurig zu sagen, Objective-C hat keine äquivalente Eigenschaft/Methode aufrufen Semantik als cat.items.append(item) in Swift.

Dies ist ähnlich:

// Objective-C 
CGRect frame = view.frame; 
view.frame = CGRectMake(frame.origin.x, 50, frame.size.width, frame.size.height) 

// Swift 
view.frame.origin.y = 50 

-

Vielleicht Apple kann implementieren, dass als NSMutableArray (oder Privatunterklasse), natürlich können Sie das beantragen. Ich bezweifle, dass Apple das tun wird, weil das kompiliert Zeit Typ Sicherheit durch Generics.

Wie dem auch sei, ich denke, Sie Categoryy wie folgt implementieren sollten:

class Categoryy: NSObject { 
    var items:[Item] = [] 

    func addItem(item:Item) { 
     items.append(item) 
    } 

    func setItem(item:Item, atIndex:Int) { 
     items[atIndex] = item; 
    } 

    // and so on .. 
} 
1

Wenn Sie ein NSMutableArray wollen, ist der einfachste Weg, gerade ist ein NSMutableArray in Swift zu verwenden. Array<T> nicht (und konnte nicht) beide gleichzeitig als (eine unveränderliche) NSArray und NSMutableArray zu verhalten - im Augenblick, was es tut verhält sich wie eine unveränderliche NSArray. Swift könnte einen eingebauten Klassentyp verwenden, der NSMutableArray entspricht, der Weg Array<T> entspricht jedoch NSArray.

Eine weitere Alternative besteht darin, eine Swift-Klasse zu verwenden, die NSMutableArray mit @objc offengelegten Methoden umhüllt, um auf die NSMutableArray zuzugreifen. Auf diese Weise können Sie auch Generics verwenden, um Objekte auf T zu beschränken.

0

Als Workaround können Sie append in der Swift-Datei mit einer Methode aufrufen, anstatt auf das Swift-Array direkt in Objective-C zuzugreifen.

Swift:

func addItem(item:Item) 
{ 
    items.append(item) 
} 

Objective-C:

[yourSwiftObject addItem:item];