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