Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
251 views
in Technique[技术] by (71.8m points)

ios - Static properties in Swift

I'm trying to convert the following Objective-C code to Swift. In my Objective-C code, there's a static variable and its accessed from a class method.

@implementation SomeClass

static NSMutableArray *_items;

+ (void)someMethod {
    [_items removeAll];
}

@end

Since you can't access types declared like this private var items = [AnyObject]() from class functions in Swift, I created a stored property for it like this.

class var items: [AnyObject] {
    return [AnyObject]()
}

And I'm trying to call a method on it from a class function like so.

class func someFunction() {
    items.removeAll(keepCapacity: false)
}

But I get this error Immutable value of type '[AnyObject]' only has mutating members named 'removeAll'.

Can anyone please tell me what's the cause of this error and how to correct it?

Thank you.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

With this code:

class var items: [AnyObject] {
    return [AnyObject]()
}

you are not creating a stored property - instead it's a computed property, and the worst part is that every time you access to it, a new instance of [AnyObject] is created, so whatever you add to it, it's lost as soon as its reference goes out of scope.

As for the error, the static computed property returns an immutable copy of the array that you create in its body, so you cannot use any of the array method declared as mutating - and removeAll is one of them. The reason why it is immutable is because you have defined a getter, but not a setter.

Currently Swift classes don't support static properties, but structs do - the workaround I often use is to define an inner struct:

class SomeClass {
    struct Static {
        static var items = [AnyObject]()
    }
}

SomeClass.Static.items.append("test")

If you want to get rid of the Static struct every time you refer to the items property, just define a wrapper computed property:

class var items: [AnyObject] {
    get { return Static.items }
    set { Static.items = newValue }
}

so that the property can be accessed more simply as:

SomeClass.items.append("test")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...