当我使用Obj-C初始化可变的Swift数组时,它会变成NSArray。

4

我正在使用Swift(2.0)创建基本模型,然后在Objective-C中控制视图。我对Swift还很陌生,希望我只是忽略了一些简单的东西,但这就是问题所在:

我在Swift中创建了一个可变数组,但当我在程序的Objective-C部分初始化数组时,它变成了NSArray,更具体地说,它变成了:Swift._SwiftDeferredNSArray

为什么它在初始化时变成不可变的?这是我的Swift代码:

import Foundation

@objc public class Model : NSObject {

    var books:[Book]

    override init(){
        self.books = [Book]()
    }

}

这是我的 Obj-c 代码:

Model *bookCollection = [[Model alloc]init];

我无法向我的bookCollection.books数组中添加对象(因为它已成为一个NSArray),当我设置断点并输入po时,我可以看到它是一个Swift._SwiftDeferredNSArraybookCollection.books应该是一个NSMutableArray您有什么想法吗?

尝试在 books 声明之前加上 dynamic 关键字。 - Qbyte
刚刚尝试了动态变量books:[Book],不幸的是它没有改变任何东西。 - Alan Scarpa
2个回答

3

bookCollection.books应该是一个NSMutableArray。

不,它不是。 Var并不意味着桥接的Objective-C对象是可变的,而是表示该属性可以被赋值。

Swift数组类型是一个结构体,而不是类。这具有重要的桥接含义。引用本身无法共享,除非将其作为inout值传递,即使是这样,也无法存储引用。如果桥接为NSMutableArray,则可能存在不可检测的可变引用,而Swift不允许这样做。

不过,您应该能够从Objective-C代码中将新的NSArray分配给您的属性。例如,以下内容应该有效:

bookCollection.books = [bookCollection.books arrayByAddingObject:myNewBook];

另一个选项是,从Swift方面将books声明为NSMutableArray


3
在Swift中,可变数组和不可变数组的区别是:
var books:[Book] // is a mutable array
let books:[Book] = [book1, book2]; // is immutable array due to let

但我认为,在桥接到ObjC时,不会遵循相同的规则。

仅仅为了修复,你可以专门使用mutableArray。

import Foundation

@objc public class Model : NSObject {

    var books:NSMutableArray = NSMutableArray();

    override init(){
        super.init();
        // other code
    }

}

你需要从数组中检索值时将其解析为Book类。

谢谢!我会将这个标记为正确答案,但是在Swift中覆盖init方法时,这是初始化数组的正确方式吗:self.books = []?还是有更合适的方式? - Alan Scarpa
有一个选项可以使用其定义来初始化它,就像我所做的那样,但是如果您在init()中初始化相同的内容,我并没有看到任何问题。 - Shoaib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接