在Swift中创建NSMutabaleArray子类

时间:2014-12-17 14:13:22

标签: swift nsmutablearray

我试图在Swift中创建一个NSMutableArray子类,它支持一个数组文字初始值设定项。

我可以创建一个简单的子类:

class MyArray: NSMutableArray {
}

初始化工作正常:

let arrayInstance: MyArray = MyArray()

但是,如果我尝试使用数组文字:

let arrayInstance: MyArray = ["one"]

它在运行时失败,[NSMutableArray initWithCapacity:]: method only defined for abstract class.

我可以添加此初始化程序,但是,因此我还必须添加其他所需的初始化程序:

class MyArray: NSMutableArray {
  override init(capacity numItems: Int) {
    super.init(capacity: numItems)
  }

  required init(coder aDecoder: NSCoder) {
      fatalError("init(coder:) has not been implemented")
  }

  required convenience init(arrayLiteral elements: AnyObject...) {
      fatalError("init(arrayLiteral:) has not been implemented")
  }
}

不幸的是,第二个必需的初始化程序会产生以下编译器错误:

  

扩展声明无法覆盖

看起来我被卡住了!任何人都可以建议一种方法来创建支持数组文字的NSMutableArray子类吗?否则,我会回到Objective-C!

1 个答案:

答案 0 :(得分:0)

这里的问题不是数组文字,也是第一次初始化不正常,你可以得到"相同"如果你这样做会崩溃:

let arrayInstance: MyArray = MyArray()
arrayInstance.count

//OR
let secondArrayInstance: MyArray = MyArray(objects: ["one"], count: 1) // method used by literals syntax

问题是继承NSMutableArray,因为它是一个类集群。 据Apple称,没有理由这样做:

  

通常没有理由继承NSArray。上课了   以及它的目的是什么 - 维护一个有序的集合   对象。但是在某些情况下可能存在自定义NSArray对象   派上用场吧。以下是一些可能性:

     

更改NSArray存储其集合元素的方式。你可能会   这样做是出于性能原因或更好的兼容性   遗留代码。

     

获取有关集合发生情况的更多信息   (例如,统计数据收集)。

类群集定义

  

类集群是Foundation框架的设计模式   广泛使用。类簇集合了许多私有   公共抽象超类下的具体子类。分组   以这种方式的类简化了公开可见的体系结构   面向对象的框架,不会降低其功能丰富性。   类集群基于抽象工厂设计模式。

子类化NSArray的替代方法

  

在制作NSArray的自定义类之前,请研究NSPointerArray   和相应的Core Foundation类型,CFArray Reference。因为   NSArray和CFArray是“免费桥接”,你可以替代   代码中NSArray对象的CFArray对象(适当的   铸件)。虽然它们是相应的类型,CFArray和NSArray   没有相同的接口或实现,你可以   有时用CFArray做一些你不能轻易做到的事情   NSArray的。例如,CFArray提供了一组回调,其中一些是回调   用于实现自定义保留释放行为。如果你   为这些回调指定NULL实现,您可以轻松获得   非保留阵列。

     

如果您要添加的行为补充了现有行为   在课堂上,你可以在NSArray上写一个类别。但请记住,   此类别对NSArray的所有实例都有效   你使用,这可能会产生意想不到的后果。或者,   你可以使用组合来达到理想的行为。

对NSArray进行子类化

要继承NSArray,我们必须重写 count objectAtIndex :方法

  

NSArray的任何子类都必须覆盖原始实例方法   count和objectAtIndex:。这些方法必须在后备上运行   您为集合元素提供的商店。

           

概念上,数组存储了许多数据项,每个数据项都是   可通过索引访问。 NSArray通过表达这个抽象概念   它的两个原始方法,count和objectAtIndex:。用这些   可以实现作为基础的方法,其他方法派生的方法;

静态数组示例

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]
    }
}

初​​始化

let months = Months()

println("My birthday month : \(months.objectAtIndex(6))")
println("The last month of the year : \(months.lastObject)")

包含对象的数组

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]
    }
}

初始化

let fruits = MyArray()
fruits.populateWith(objects: ["Apple", "Banana", "Orange", "Pear", "Cherry"])

println("Fruits count : \(fruits.count)")

子类化NSMutableArray

与NSArray相同,但我们必须重写这些方法:

  • 计数
  • objectAtIndex:
  • insertObject:atIndex:
  • removeObjectAtIndex:
  • ADDOBJECT:
  • removeLastObject
  • replaceObjectAtIndex:withObject:

我可以根据需要添加示例

结论

我们可以在swift中继承NSArray(仅在使用默认初始值设定项 init()时),但我们还不能使用其他初始值设定项(如initWithObjects:count :)。

所以,我同意你的意见,目前,最好的解决方案是在Objective-c中继承Class Clusters

Class Clusters documentation

NSArray documentation

希望有所帮助