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.
Static variables are those variables whose values are shared among all the instance or object of a class. When we define any variable as static, it gets attached to a class rather than an object. The memory for the static variable will be allocation during the class loading time.
Static properties are used when we'd like to store class-level data, also not bound to an instance. The syntax is: class MyClass { static property = ...; static method() { ... } }
In Swift, Static let and Static var are considered as Type Properties, which means that they can be accessed by their type. In this example, two properties have static keyword, one is constant and another one is variable.
Where static and class differ is how they support inheritance: When you make a static property it becomes owned by the class and cannot be changed by subclasses, whereas when you use class it may be overridden if needed.
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")
Updated to Swift1.2
In Swift1.2[Xcode6.3], you can declare static properties using keyword static, also you can declare static methods using keyword class or static.
class SomeClass { // use static modifier to declare static properties. static var items: [AnyObject]! // use class modifier to declare static methods. class func classMethod() { items.removeAll(keepCapacity: false) } // use static modifier to declare static methods. static func staticMethod() { items.removeAll(keepCapacity: false) } }
EDIT:
The difference between static
and class
modifier is that static
is just an alias for "class final",so methods modified with static
can not be overridden in subclasses.
Thanks @Maiaux's
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