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

时间:2014-09-19 09:42:28

标签: objective-c swift nsmutablearray nsarray xcode6

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

class Categoryy: NSObject {

    var items = Array<Item>()

}

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

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

3 个答案:

答案 0 :(得分:6)

这是因为items属性实际上是不可变的

As you know,由于Swift中基于struct的{​​{1}}实施的性质,以下代码不会影响Array

cat.items

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

let cat = Categoryy()

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

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

[cat.items addObject:item]

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

不幸的是,Objective-C的不具有等效属性/方法调用的语义id _items = [cat items]; [_items addObject:item]; 在夫特

这类似于:

cat.items.append(item)

-

也许Apple可以将其实现为// 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 (或私有子类),当然您可以请求。 我怀疑Apple会这样做,因为这会破坏Generics的编译时类型安全性。

无论如何,我认为,您应该像这样实施NSMutableArray

Categoryy

答案 1 :(得分:1)

如果您想要NSMutableArray,最简单的方法就是在Swift中使用NSMutableArrayArray<T>并不(并且不能)同时表现为(不可变的)NSArrayNSMutableArray - 现在,它的行为就像是作为一个不可变的NSArray。 Swift可以使用与NSMutableArray对应的内置类类型Array<T>对应NSArray的方式。

另一种方法是使用一个Swift类,用NSMutableArray包含@objc个公开的方法来访问NSMutableArray。这也允许您使用泛型将项目约束为T

答案 2 :(得分:0)

作为一种解决方法,您可以使用方法在Swift文件中调用append,而不是直接在Objective-C中访问Swift数组。

夫特:

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

目标-C:

[yourSwiftObject addItem:item];