Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free.

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?

share|improve this question
    
Try putting the dynamic keyword in front of the books declaration. –  Qbyte 4 hours ago
    
Just tried dynamic var books:[Book] , unfortunately it didn't change anything. –  Alan_s 4 hours ago

2 Answers 2

up vote 1 down vote accepted

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.

share|improve this answer
    
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? –  Alan_s 3 hours ago
    
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(). –  Shoaib 3 hours ago

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.