The problem here is not in array literals, also the first initialization does not work fine, you may get the βsameβ failure if you do this:
let arrayInstance: MyArray = MyArray() arrayInstance.count //OR let secondArrayInstance: MyArray = MyArray(objects: ["one"], count: 1) // method used by literals syntax
The problem is subclassing NSMutableArray because it is a cluster of classes. According to Apple, there is no reason for this:
Normally there is no reason for a subclass of NSArray. A class does well that it is designed to maintain an ordered collection of objects. But there are times when a custom NSArray can come in handy. Here are a few possibilities:
Change how NSArray stores items in its collection. You could do this for performance reasons or for better compatibility with legacy code.
Obtaining additional information about what is happening with the collection (for example, collecting statistics).
Cluster Cluster Definition
Class Clusters is a design pattern that Foundation supports is widely used. Cluster groups group a number of private concrete subclasses under a public abstract superclass. Grouping classes in this way simplifies the publicly visible architecture of an object-oriented structure without reducing its functional richness. Class clusters are based on the Abstract Factory design pattern.
Alternatives to NSArray Subclassification
Before creating your own NSArray class, examine the NSPointerArray and its corresponding Core Foundation type, CFArray Reference. Because NSArray and CFArray are "duty free bridges", you can replace the CFArray for the NSArray in your code (with the appropriate Casting). Although they are appropriate types, CFArray and NSArray do not have the same interfaces or implementations, and you can sometimes do something with CFArray, which NSArray cannot handle easily. For example, CFArray provides a set of callbacks, some of which are designed to implement custom save-release behavior. if you specify NULL implementations for these callbacks, you can easily get an unsupported array.
If the behavior you want to add complements an existing class, you can write a category in NSArray. However, keep in mind that this category will apply to all instances of NSArray that you are using, and this may have unintended consequences. Alternatively, you can use the composition to achieve your desired behavior.
Subclass NSArray
In the NSArray subclass, we must override the count and objectAtIndex: methods
Any subclass of NSArray must override the primitive instance methods count and objectAtIndex :. These methods should work on the basis that you provide for the elements of the collection.
In concept, an array stores a number of data elements, each of which is accessible by index. NSArray expresses this abstract concept through its two primitive methods, count and objectAtIndex :. With these methods as a base, other derived methods are
Static Matrix Example
class Months: NSArray { let months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ] override var count: Int { get { return months.count } } override func objectAtIndex(index: Int) -> AnyObject { assert(index < count, "The index is out of bounds") return months[index] } }
Initialization
let months = Months() println("My birthday month : \(months.objectAtIndex(6))") println("The last month of the year : \(months.lastObject)")
Array with objects
class MyArray: NSArray { var array: [AnyObject] = [] func populateWith(#objects: [AnyObject]) { self.array = objects } override var count: Int { get { return array.count } } override func objectAtIndex(index: Int) -> AnyObject { assert(index < count, "The index is out of bounds") return array[index] } }
Initialization
let fruits = MyArray() fruits.populateWith(objects: ["Apple", "Banana", "Orange", "Pear", "Cherry"]) println("Fruits count : \(fruits.count)")
Subclass NSMutableArray
The same applies to NSArray, but we must override these methods:
- number
- objectAtIndex:
- insertObject: atIndex:
- removeObjectAtIndex:
- AddObject:
- removeLastObject
- replaceObjectAtIndex: withObject:
I can add an example if necessary
Conclusion
We can subclass NSArray into swift (only when using the default initializer init ()), but we cannot (yet) use other initializers (e.g. initWithObjects: count :).
So, I agree with you, at the moment, the best solution is to subclass class clusters in objective-c
Class Cluster Documentation
NSArray Documentation
Hope that helps