如何覆盖此类属性?

时间:2017-03-21 20:16:02

标签: ios swift

struct SectionData {
    var items : [LiveCellObjectProtocol] 
    var title: String? = nil
    subscript(index: Int) -> LiveCellObjectProtocol {
        return items[index]
    }
}

extension SectionData{
    init(title: String? = nil){
        self.title = title
        self.items = []
    }
}

class LiveCellTableViewController: UIViewController  {

    var sections: [SectionData] = {
        return [SectionData(title: "aaa"), SectionData(title: "bbb"), SectionData(title: "ccc")]
    }()
}

如果我将其子类化,如何覆盖sections?我想改变标题。

这不会构建。

class SomeChild: LiveCellTableViewController {
    override var sections: [SectionData] = {
        return [SectionData(title:  nil), SectionData(title: "Mutual"), SectionData(title: "Connections")]
    }()
}

4 个答案:

答案 0 :(得分:1)

override属性不能是存储属性。这就是Swift的工作方式(如果你考虑一下,这是有道理的)。我在my book中列出了如下可能性:

  
      
  • 如果超类属性是可写的(存储属性或带有setter的计算属性),则子类的覆盖可能包含   将setter观察者添加到此属性。

  •   
  • 或者,子类的覆盖可以是计算属性。在那种情况下:

         
        
    • 如果存储了超类属性,则计算子类的值   属性覆盖必须同时具有getter和setter。

    •   
    • 如果计算了超类属性,则计算子类的值   属性覆盖必须重新实现所有的访问器   超类实现。如果超类属性是只读的(它具有   只是一个吸气剂),覆盖可以添加一个设定器。

    •   
  •   

所以在这里做你想做的事情的方法是覆盖,而不是属性,而是覆盖类的初始值设定项。这是一个高度简化的例子:

class C {
    var sections : [Int] = [1,2,3]
}

class CC : C {
    override init() {
        super.init()
        super.sections = [4,5,6]
    }
}

C().sections // [1,2,3]
CC().sections // [4,5,6]

答案 1 :(得分:0)

摆脱等号:

var sections: [SectionData] {
  return [SectionData(title: "aaa"), SectionData(title: "bbb"), SectionData(title: "ccc")]
}

这就是Xcode想要括号的原因。使用等号,您的代码块定义了一个内联函数,()调用该函数,使用结果初始化您的变量。如果没有(),您会尝试将函数分配给数组。

如果没有=,您可以使用getter定义属性,(我假设)就是您想要的。

答案 2 :(得分:0)

您无法在swift中覆盖存储的属性。您可以使用私有存储和计算属性来解决此问题。像这样:

 //: Playground - noun: a place where people can play

import Cocoa

struct SectionData {
    let title: String
}

class ParentClass {

    private let defaultSections = [SectionData(title: "Parent")]

    var sections: [SectionData] {
        return defaultSections
    }

}

class ChildClass: ParentClass {

    private let childSections = [SectionData(title: "Child")]

    override var sections: [SectionData] {
        return childSections
    }

}

// If you wanted a child who appends sections

class AnotherChildClass: ParentClass {

    private let childSections = [SectionData(title: "Child")]

    override var sections: [SectionData] {
        return super.sections + childSections
    }

}

此外,因为在您的示例中,您只是覆盖父类功能而您的属性是不可变的,所以您可以将它作为init期间传入的参数。

//: Playground - noun: a place where people can play

import Cocoa

struct SectionData {
    let title: String
}

class ParentClass {

    let sections: [SectionData]

    init(sections: [SectionData]) {
        self.sections = sections
    }
}

class ChildClass: ParentClass {

}

let parent = ParentClass(sections: [SectionData(title: "Parent")])
let child = ChildClass(sections: [SectionData(title: "Child")])

答案 3 :(得分:0)

只需在创建子类后更改子类中的值,如果您从故事板中加载它,最简单的位置在awakeFromNib

class SomeChild: LiveCellTableViewController {
    override func awakeFromNib() {
        super.awakeFromNib()

        sections = [SectionData(title:  nil), SectionData(title: "Mutual"), SectionData(title: "Connections")]
    }
}