A simple Swift class has a field of type var Array. When the class is adapted to Objective-C the field type is exposed as NSArray (immutable) while it should be NSMutableArray (mutable)
class Categoryy: NSObject {
var items = Array<Item>()
}
The Categoryy swift class is adapted to Objective-C in the Xcode-generated header MODULE_NAME-swift.h file as following:
SWIFT_CLASS("_TtC8waiterio9Categoryy")
@interface Categoryy : NSObject
@property (nonatomic, copy) NSArray * items;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
is there a way for the var items : Array field to be converted to a mutable NSMutableArray in Objective-c?
That is because items property is actually immutable.
As you know, because of the nature of struct based implementation of Array in Swift, following code does not affect cat.items.
let cat = Categoryy()
var _items = cat.items
_items.append(item)
Instead, you have to call like this
cat.items.append(item)
On the other hand, in Objective-C, [cat.items addObject:item] is exactly same as following:
id _items = [cat items];
[_items addObject:item];
That is very similar to non-working Swift code.
Sad to say, Objective-C does not have equivalent property/method calling semantics as cat.items.append(item) in Swift.
This is similar to:
// 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
--
Maybe Apple can implement that as NSMutableArray(or private subclass), of course you can request that.
I doubt Apple will do that, because that breaks compile time type safety by Generics.
Anyway, I think, you should implement Categoryy like this:
class Categoryy: NSObject {
var items:[Item] = []
func addItem(item:Item) {
items.append(item)
}
func setItem(item:Item, atIndex:Int) {
items[atIndex] = item;
}
// and so on ..
}
If you want an NSMutableArray, the easiest way is to just use an NSMutableArray in Swift. Array<T> doesn't (and couldn't) both behave as (an immutable) NSArray and NSMutableArray at the same time - right now, what it does behave as is as an immutable NSArray. Swift could use a built-in class type that corresponds to NSMutableArray the way Array<T> corresponds to NSArray though.
Another alternative is to use a Swift class wrapping an NSMutableArray with @objc exposed methods to access the NSMutableArray. That also lets you use generics to constrain items to T.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With