【问题标题】:Mutable Swift array becomes NSArray when I initialize with Obj-C当我使用 Obj-C 初始化时,可变 Swift 数组变为 NSArray
【发布时间】:2015-12-01 05:31:36
【问题描述】:

我在 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

有什么想法吗?

【问题讨论】:

  • 尝试将 dynamic 关键字放在 books 声明的前面。
  • 刚刚尝试了 dynamic var books:[Book] ,不幸的是它没有改变任何东西。

标签: ios objective-c arrays swift swift2


【解决方案1】:

在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 Class。

【讨论】:

  • 谢谢!我会将此标记为正确答案,但这是在 ovverride init 方法中在 Swift 中初始化我的数组的正确方法:self.books = [] 还是有更合适的方法?
  • 有一个选项可以像我一样用它的定义来初始化它,但如果你在 init() 中初始化它,我看不到任何问题。
【解决方案2】:

bookCollection.books 应该是一个 NSMutableArray。

不,不是。 Var 并不意味着桥接的 Objective-C 对象是可变的:它意味着可以分配属性。

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

不过,您应该能够从 Objective-C 代码中为您的属性分配一个新的 NSArray。例如,这应该有效:

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

显然,您的另一个选择是从 Swift 方面将 books 声明为 NSMutableArray

【讨论】:

    猜你喜欢
    • 2021-06-08
    • 1970-01-01
    • 2023-02-23
    • 1970-01-01
    • 2014-04-21
    • 2013-03-06
    • 2017-03-20
    • 2013-02-04
    • 2016-11-26
    相关资源
    最近更新 更多