4

I'm creating my base models in Swift(2.0) and then controlling the views in Objective-C. I'm still new to Swift, so hopefully I'm just overlooking something simple, but here is the problem:

I’m making a mutable array in Swift, but when I initialize the array in my Objective-c portion of the program, it becomes an NSArray, more specifically it becomes: Swift._SwiftDeferredNSArray

Why is it becoming immutable when I initialize? Here’s my Swift code:

import Foundation

@objc public class Model : NSObject {

    var books:[Book]

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

}

And here’s my Obj-c Code;

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

I’m unable to add objects to my bookCollection.books array (because it has become an NSArray) and when I set a breakpoint and po it, I can see that it is a Swift._SwiftDeferredNSArray. bookCollection.books is supposed to be an NSMutableArray.

Any thoughts?

2
  • Try putting the dynamic keyword in front of the books declaration. Commented Sep 5, 2015 at 1:11
  • Just tried dynamic var books:[Book] , unfortunately it didn't change anything. Commented Sep 5, 2015 at 1:14

2 Answers 2

3

In swift, the difference between mutable and immutable array is;

var books:[Book] // is a mutable array
let books:[Book] = [book1, book2]; // is immutable array due to let

but I don't think, same rule is followed when bridging to ObjC.

Just for a fix, you may have mutableArray specifically.

import Foundation

@objc public class Model : NSObject {

    var books:NSMutableArray = NSMutableArray();

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

}

You will need to parse the values to Book Class when retrieving from the array.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! I'll mark this as the correct answer but is this the correct way to initialize my array in Swift in the ovverride init method: self.books = [] Or is there a more proper way?
There is an option to initialize it with it's definition as I did but I do not see any issue if you initialize the same in your init().
3

bookCollection.books is supposed to be an NSMutableArray.

No, it is not. Var does not mean that the bridged Objective-C object is to be mutable: it means that the property can be assigned to.

The Swift array type is a structure, not a class. This has important bridging implications. The reference itself cannot be shared without passing it as an inout value, and even then the references cannot be stored. If it bridged as a NSMutableArray, it would be possible to have undetectable mutating references, and Swift does not allow that.

You should be able to assign a new NSArray to your property from Objective-C code, though. For instance, this should work:

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

Your other option, obviously, is to declare books as a NSMutableArray from the Swift side.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.