类型为var Array的Swift类字段将转换为不可变的NSArray而不是NSMutableArray

Gio*_*gio 11 objective-c nsmutablearray nsarray swift xcode6

一个简单的Swift类有一个var array类型的字段.当类适应Objective-C时,字段类型公开为NSArray(不可变),而它应该是NSMutableArray(可变)

class Categoryy: NSObject {

    var items = Array<Item>()

}
Run Code Online (Sandbox Code Playgroud)

Classy swift类适用于Xcode生成的头文件MODULE_NAME-swift.h文件中的Objective-C,如下所示:

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

是否有一种方法可以将var项:Array字段转换为Objective-c中的可变NSMutableArray?

rin*_*aro 6

那是因为items财产实际上是不可变的.

如您所知,由于Swift 中struct基于实现的性质Array,以下代码不会影响cat.items.

let cat = Categoryy()

var _items = cat.items
_items.append(item)
Run Code Online (Sandbox Code Playgroud)

相反,你必须像这样打电话

cat.items.append(item)
Run Code Online (Sandbox Code Playgroud)

另一方面,在Objective-C中,[cat.items addObject:item]与以下内容完全相同:

id _items = [cat items];
[_items addObject:item];
Run Code Online (Sandbox Code Playgroud)

这与非工作的Swift代码非常相似.

遗憾的是,Objective-C没有像cat.items.append(item)Swift 那样调用语义的等效属性/方法.

这类似于:

// 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
Run Code Online (Sandbox Code Playgroud)

-

也许Apple可以将其实现为NSMutableArray(或私有子类),当然您可以请求.我怀疑Apple会这样做,因为这会破坏Generics的编译时类型安全性.

无论如何,我想,你应该这样实现Categoryy:

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 ..
}
Run Code Online (Sandbox Code Playgroud)