[Swift] The Swift Programming Language - 控制流/閉包/枚舉/屬性/方法/下標/繼承

Control Flow

For in & For-Condition-Increment

主要有for in以及傳統(tǒng)的for還有switch梁剔,例如for index in 1...5陪踩。這種知識循環(huán)內(nèi)使用的對象例如這里的index,是不需要提前用let聲明的刹勃,但是如果循環(huán)外你也想用就要先聲明了哦~ 如果是想遍歷string的字符還可以for character in "Hello"

如果你不需要用到index,甚至可以for _ in 1...5坐梯,這樣其實就是循環(huán)了5次价卤,然后你在block里面是拿不到這是第幾次循環(huán)的。

對于dict之類的也可以用for in來執(zhí)行:

let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
    print("\(animalName)s have \(legCount) legs")
}

如果是increment的那種遍歷for (var index = 0; index < 3; ++index)在swift3以后已經(jīng)不能用了闯狱,只能改成用for in + enumerated()了~ 還可以用for (index, value) in numberList.enumerated()

for animal in numberOfLegs.enumerated() {
    print("the \(animal.offset)th animal is \(animal)")
}

輸出:
the 0th animal is (offset: 0, element: (key: "spider", value: 8))
the 1th animal is (offset: 1, element: (key: "ant", value: 6))
the 2th animal is (offset: 2, element: (key: "cat", value: 4))

如果你想反向遍歷還可以醬紫numberList.enumerated().reversed()


Switch

和正常的switch的區(qū)別是煞赢,這里不用break,默認就是每個case會break哄孤,如果你需要不break直接添加fall through即可照筑。另外的區(qū)別就是swift里面的switch不僅僅可以針對int,還可以針對string瘦陈、character之類的~

而且你還可以把多個case合成一個例如case a凝危、case b合成為case a, b

并且case還可以提供range晨逝,例如一個int是99蛾默,你可以case 1...100

還可以用_來匹配一個任意字符:

let somePoint = (1, 1)
switch somePoint {
case (0, 0):
    print("(0, 0) is at the origin")
case (_, 0):
    print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
    print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
    print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
    print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}

還可以用臨時常量來在case里面使用:case (let x, 0): print("on the x-axis with an x value of \(x)")咏花,這里用let因為其實后面是不會改的~

case是不能有空描述的趴生,所以如果想忽略case可以通過break

  • where

switch還可以和where結(jié)合來check一些以前要用 if 來判斷的事兒:

let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
    print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
    print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
    print("(\(x), \(y)) is just some arbitrary point")
}
  • fallthrough

會在滿足了某個case以后繼續(xù)判斷下一個case昏翰。但不保證一定會到最后哦苍匆,如果中間某個滿足了并且沒有fallthrough就會跳出啦

let sum = 10
switch sum {
case 1,2,10:
    print("A")
    fallthrough
case 3,2,10:
    print("B")
case 4,2,10:
    print("C")
default:
    print("D")
}

輸出:
A
B
  • label

swift還支持類似goto那種的label,你可以給代碼段加上label棚菊,然后break到那個label或者continue到那個label的地方浸踩。


Functions

func sayHello(personName: String) -> String {
    let greeting = "Hello, " + personName + "!"
    return greeting
}

print(sayHello(personName: "Anna"))

沒有return type的func其實也有return,只是類型是Void统求,也就是一個空的元組检碗,還可以用()來替代。

可以返回多個數(shù)值例如:func count(string: String) -> (vowels: Int, consonants: Int, others: Int)码邻,注意一定要返回一個有名字的元組

func還可以區(qū)分內(nèi)外名字~ 例如你有個內(nèi)部變量叫sum折剃,然后你傳入的參數(shù)還是sum,如果覺得重復像屋,可以讓這個參數(shù)的外部名為sum怕犁,內(nèi)部名為s,例如醬紫func join(string s1: String, toString s2: String, withJoiner joiner: String)

func someFunction(externalParameterName localParameterName: Int) { // function body goes here, and can use localParameterName
// to refer to the argument value for that parameter
}

你還可以給參數(shù)加默認值:func someFunction(externalParameterName localParameterName: Int = 0)己莺,這樣就可以不給出參數(shù)了~ 例如someFunction()這么調(diào)用~

swift也支持可變參數(shù)傳入...奏甫,也就是你可以傳入0或者n個同類型的參數(shù),內(nèi)部可以用數(shù)組的形式使用凌受,但每個func最多有一個這樣的參數(shù)阵子,要不就混啦,以及必須放到最后

func arithmeticMean(numbers: Double...) -> Double {
    var total: Double = 0
    for number in numbers {
        total += number
    }
    
    return total / Double(numbers.count)
}

默認的傳入?yún)?shù)的類型都是let的胜蛉,也就是不可變的挠进,在函數(shù)范圍內(nèi)你只能使用外邊傳入的參數(shù)但是不能改變它,如果你想改變它的話誊册,需要將它聲明為var奈梳,這樣的話其實是給了你一個原參數(shù)的可變copy~
func alignRight(var string: String, count: Int, pad: Character) -> String

因為如果用var修改其實并沒有改到原來的值,所以如果你想修改傳入的參數(shù)解虱,需要加inout注意哦攘须,`inout`如果用的話就不能使用`var`或者`let`來修飾了哦func swapTwoInts(inout a: Int, inout b: Int)

調(diào)用的時候需要用&來修飾傳入的參數(shù)哦:

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)

函數(shù)類型就是他的輸入&輸出,例如(Int, Int) -> Int殴泰,就是輸入兩個int輸出一個int~ 如果要是沒有輸入?yún)?shù)也沒有輸出就是() -> ()于宙,在swift里面可以簡化為()

通過函數(shù)類型就可以定義函數(shù)了:var mathFunction: (Int, Int) -> Int = addTwoInts

你可以用函數(shù)類型來定義參數(shù)悍汛,其實函數(shù)類型和其他類型例如Int之類的完全是一樣的:

func printMathResult(mathFunction: (Int, Int) -> Int, a: Int, b: Int) { println("Result: \(mathFunction(a, b))")
}
printMathResult(addTwoInts, 3, 5) // prints "Result: 8"

如果return type是func會看起來很神奇:chooseStepFunction就是return了一個函數(shù)~

func stepForward(input: Int) -> Int {
    return input + 1
}
func stepBackward(input: Int) -> Int {
    return input - 1
}
func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    return backwards ? stepBackward : stepForward
}

你不僅可以定義全局的func捞魁,還可以在函數(shù)體內(nèi)定義nested functions,類似醬紫:

func chooseStepFunction(backwards: Bool) -> (Int) -> Int {
    func stepForward(input: Int) -> Int { return input + 1 }
    func stepBackward(input: Int) -> Int { return input - 1 }
    return backwards ? stepBackward : stepForward
}

Closures

  • Global functions are closures that have a name and do not capture any values. 正常的函數(shù)不捕捉(增加引用)
  • Nested functions are closures that have a name and can capture values from their enclosing function. 函數(shù)內(nèi)的會捕捉傳入自己的參數(shù)
  • Closure expressions are unnamed closures written in a lightweight syntax that can capture values from their surrounding context. 閉包也會捕捉自己區(qū)域內(nèi)的參數(shù)

閉包是醬紫的离咐,閉包中也可以用let / var/ inout的:

{ ( parameters ) -> return type in statements
}

舉個逆序排序的例子:

reversed = sort(names, { (s1: String, s2: String) -> Bool in 
  return s1 > s2
})

in代表著閉包的聲明已經(jīng)結(jié)束了谱俭,下面就是block的實現(xiàn)了奉件。

當類型是可以infer的時候,例如參數(shù)的type就是(string, string) -> Bool昆著,那么傳入的內(nèi)容就可以不用標明類型了县貌,因為一定是和期待的類型一致的例如:reversed = sort(names, { s1, s2 in return s1 > s2 } )

如果block的body只有return xxx,甚至可以省略return改成醬紫reversed = sort(names, { s1, s2 in s1 > s2 } )

swift的$0, $1, $2可以用于指代第一凑懂、二煤痕、三個參數(shù)。所以上面的可以再簡化為reversed = sort(names, { $0 > $1 } )這種情況下參數(shù)會和sort的定義去核對參數(shù)的類型接谨,然后放到0 or1里面摆碉,這樣就可以省略參數(shù)列表了,這里 in 也是可以省略的脓豪,因為整個block都是由body組成巷帝。

因為string其實有大小比較的方法,所以上面的還可以再簡化一下變?yōu)?code>reversed = sort(names, >)醬紫扫夜。

如果closure恰好是尾調(diào)用锅睛,正好是參數(shù)的最后一個,并且這個block會比較長历谍,那么可以調(diào)用的時候把closure放到外邊~

func someFunctionThatTakesAClosure(closure: () -> ()) {
    // function body goes here
}

// here's how you call this function without using a trailing closure:
someFunctionThatTakesAClosure (closure: {
    // closure's body goes here
})

someFunctionThatTakesAClosure() {
    // how you call this function with a trailing closure instead:
}

如果是這樣簡化一下现拒,上面的sort還以改為醬紫:reversed = sort(names) { $0 > $1 }

當只有一個參數(shù)并且是closure的時候望侈,調(diào)用甚至可以忽略函數(shù)的()印蔬,這個主要是在array的map方法之類的時候可以使用

let strings = numbers.map {
    (var number) -> String in
    var output = ""
    while number > 0 {
        output = digitNames[number % 10]! + output
        number /= 10 }
    return output
}

這里number不需要指定type是因為它作為參數(shù)是可以infer出來的,然后聲明為var是因為需要在之后的block里面修改脱衙。(swift 4以后好像不能給入?yún)⒓觱ar修飾以后修改了侥猬,強制是let的,但inout可以

值的捕獲

先舉個nest func的例子:

func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementor() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementor
}

incrementor 其實是使用了外部的 runningTotal 以及 amount捐韩,他自己內(nèi)部沒有定義退唠。這個時候其實是捕捉了外部的變量的~

func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementor() -> Int {
        runningTotal += amount
        return runningTotal
    }
    runningTotal = 10
    return incrementor
}

var i1 = 0
i1 = makeIncrementor(forIncrement: 10)() //20
i1 = makeIncrementor(forIncrement: 5)() //15
i1 = makeIncrementor(forIncrement: 6)() //16
i1 = makeIncrementor(forIncrement: 7)() //17

可以看到closure的捕捉不是字面量的copy,因為在它之后修改runningTotal的值也生效了荤胁,所以我猜測這里還是指針的捕捉瞧预。并且如果你在closure里面改了runningTotal并立刻調(diào)用這個closure,會發(fā)現(xiàn)外部的數(shù)值變化了仅政,這里是很類似__block的捕捉的垢油。也就是這closure是捕捉了外部變量的引用的,確保不會被釋放(所以這里需要注意循環(huán)引用哦)

注意這里不是static圆丹,所以每次closure執(zhí)行的時候runningTotal都是新的值滩愁,另外swift 3已經(jīng)不支持局部static了,如果想讓屬性static辫封,需要把static修飾類里面的變量硝枉,不能是函數(shù)里面的局部變量

closure是引用類型廉丽,多個變量如果指向同一個closure,實際上只是使用了同一個引用


枚舉

定義類似醬紫:

enum CompassPoint {
    case North
    case South
    case East
    case West
}

還可以一行寫~
enum Planet {
  case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune
}

如果初始化變量的時候已經(jīng)是某個枚舉了妻味,之后就可以只提供值不寫類型正压,因為這個變量的類型可以infer出來,例如這樣初始化var directionToHead = CompassPoint.West弧可,然后改的話只要醬紫就好directionToHead = .East

switch的時候也是蔑匣,只要簡寫值就可以啦~

枚舉還可以用于存儲關(guān)聯(lián)對象哦~

enum Barcode {
  case UPCA(Int, Int, Int) 
  case QRCode(String)
}

定義類型Barcode的對象劣欢,并且可以關(guān)聯(lián)規(guī)定的元組:var productBarcode = Barcode.UPCA(8, 85909_51226, 3)或者productBarcode = .QRCode("ABCDEFGHIJKLMNOP")

在switch的時候可以把關(guān)聯(lián)的元組提取出來:

switch productBarcode {
    case .UPCA(let numberSystem, let identifier, let check):
        print("UPC-A with value of \(numberSystem), \(identifier), \(check).")
    case .QRCode(let productCode):
        print("QR code with value of \(productCode).")
}

如果枚舉需要默認值raw value可以醬紫:

enum ASCIIControlCharacter: Character {
    case Tab = "\t"
    case LineFeed = "\n"
    case CarriageReturn = "\r"
}

如果想從枚舉值變?yōu)閞aw value可以用Planet.Earth.toRaw()棕诵,如果想反向從value變枚舉值可以Planet.fromRaw(7)這樣得到的就是枚舉類型的數(shù)據(jù)啦


類和結(jié)構(gòu)體

Classes and structures in Swift have many things in common. Both can:

  • Define properties to store values
  • Define methods to provide functionality
  • Define subscripts to provide access to their values using subscript syntax
  • Define initializers to set up their initial state
  • Be extended to expand their functionality beyond a default implementation
  • Conform to protocols to provide standard functionality of a certain kind

Classes have additional capabilities that structures do not:

  • Inheritance enables one class to inherit the characteristics of another.

也就是類和結(jié)構(gòu)體很多方面都是一致的,除了class有繼承的能力

Structures are always copied when they are passed around in your code, and do not use reference counting. struct傳遞的時候都是值引用哦

定義:(注意類名大駝峰凿将,屬性名小駝峰)

class SomeClass {
// class definition goes here
}
struct SomeStructure {
// structure definition goes here
}

swift允許你直接set給你的屬性的屬性一個value校套,不用創(chuàng)建一個新的對象然后賦值屬性:someVideoMode.resolution.width = 1280

struct是有一個默認的初始化函數(shù)的,只要指定參數(shù)名即可牧抵,例如let vga = Resolution(width: 640, height: 480)笛匙,但是class是沒有默認的初始化函數(shù)的哦

struct和枚舉都是值類型,也就是在傳遞的時候是通過copy傳遞的犀变,不是傳遞引用妹孙。This means that any structure and enumeration instances you create—and any value types they have as properties—are always copied when they are passed around in your code. 但是class傳遞是引用傳遞哦

判斷class的對象相等的時候,用===是嚴格相等获枝,就是指向同一個對象地址蠢正,但是==可能是即使對象不是同一個,但各個參數(shù)一致就算同一個對象省店。

所以其實考慮用struct還是class的時候嚣崭,可以考慮一下傳遞的時候希望是值引用還是指針引用~ 所以其實一般用的還是class

NSArray 和 NSDictionary 傳遞的時候是通過refer而不是值哦~ 但是array以及dictionary不是醬紫的,是傳遞的copy懦傍,所以swift里面的數(shù)組和詞典和OC的還是有些許不一樣的

如果數(shù)組里面存的是值類型雹舀,在array賦值的時候會把自己重新copy一下付給新的變量,如果里面存的是引用類型粗俱,則會復制指針:

var ages = ["Peter": 23, "Wei": 35, "Anish": 65, "Katya": 19]
var copiedAges = ages
copiedAges["Peter"] = 24
print(ages["Peter"])

array比較神奇说榆,copy只會在你可能會append / delete / insert / replace的時候再去copy,有點類似線程fork寸认,于是在沒有操作的時候娱俺,其實指向的還是一個array。

var a = [1, 2, 3]
var b = a
var c = a
a[0] = 42
print(a[0]) // 42
print(b[0]) // 42
print(c[0]) // 42

但是如果你append一個對象就不一樣了哦:

a.append(4)
a[0] = 777
print(a[0]) // 777
print(b[0]) // 42
print(c[0]) // 42

==!=可以用于判斷兩個隊列是不是具有相同的member废麻,而非指向array的指針一致荠卷。


屬性

對于存儲屬性而言,如果是struct的屬性烛愧,并且把struct對象賦值給一個let對象油宜,那么這個對象的屬性是不能被修改的掂碱,即使屬性是var聲明的:

struct FixedLengthRange {
    var firstValue: Int
    let length: Int
}

let rangeOfThreeItems = FixedLengthRange(firstValue: 0, length: 3)
rangeOfThreeItems.firstValue = 6
// 將會報錯Cannot assign to property: 'rangeOfThreeItems' is a 'let' constant

This behavior is due to structures being value types. When an instance of a value type is marked as a constant, so are all of its properties. 當值類型被標記為constant,它的所有屬性也是constant慎冤。然而疼燥,對于class不是這樣的哦。

@lazy表明的屬性就是懶加載的蚁堤,注意需要表明為var不能是let哦醉者,因為只有在第一次被使用的時候這個屬性才會init,也就是最開始是沒有值的~例如lazy var importer = DataImporter()

懶加載比較適用于初始化比較耗費資源的(比如init的時候需要做I/O文件操作的)披诗,以及可能初始化的值會和其他有關(guān)系的撬即,需要等這個對象init完再有的屬性~~

注意swift是木有實例變量的概念的,也就是屬性和實例變量都是一個呈队,不會有_屬性名的對象啦剥槐,也是防止不知道操作哪個吧,雖然OC轉(zhuǎn)過來不太習慣沒有實例變量

計算屬性是會計算一個value宪摧,而不是存儲一個值粒竖。they provide a getter and an optional setter to retrieve and set other properties and values indirectly

struct Point {
    var x = 0.0
    var y = 0.0
}
struct Size {
    var width = 0.0
    var height = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    var center : Point {
        get {
            print("\(#function) getter is invoked!")
            let centerX = origin.x + size.width / 2.0
            let centerY = origin.y + size.height / 2.0
            return Point(x: centerX, y: centerY)
        }
        set(newcenter) {
            print("\(#function) setter is invoked!")
            origin.x = newcenter.x - size.width / 2.0
            origin.y = newcenter.y - size.height / 2.0
        }
    }
}

var squre = Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 10.0, height: 10.0))
let initcenter = squre.center
squre.center = Point(x: 15.0, y: 15.0)

這里rect的center就是計算屬性~ 是由origin和size計算出來的~ 提供getter以及setter。默認setter的參數(shù)是newValue几于,如果不需要重命名可以不寫(newcenter)的蕊苗,直接使用newValue即可。

如果只有g(shù)et的計算屬性就是read-only的~ 如果只有g(shù)et的情況下其實是可以省略get以及花括號的沿彭,變?yōu)獒u紫:

struct Rect {
    var origin = Point()
    var size = Size()
    var center : Point {
        print("\(#function) getter is invoked!")
        let centerX = origin.x + size.width / 2.0
        let centerY = origin.y + size.height / 2.0
        return Point(x: centerX, y: centerY)
    }
}

屬性值觀察器willSet(默認參數(shù)是newValue)以及didSet(默認參數(shù)是oldValue)其實就類似KVO~ 會在屬性set之前以及之后調(diào)用~

如果這個屬性的setter你有朽砰,直接在setter里面做你想在set之前以及之后做的事情即可,注意init的時候賦值不會觸發(fā)willset didset哦

var totalSteps: Int = 0 {
    willSet(newTotalSteps) {
        print("About to set totalSteps to \(newTotalSteps)")
    }
    didSet {
        if totalSteps > oldValue {
            print("Added \(totalSteps - oldValue) steps")
        }
    }
}

如果在didSet里面改變屬性值是不會再次觸發(fā)willSet和didSet的膝蜈,但也可以成功改值~

全局變量or常量默認是lazy的锅移,所以不用特殊標記@lazy,但是局部變量不是~

類屬性是不屬于instance的饱搏,而且必須設(shè)置default值非剃,因為他和屬于對象的property不一樣,因為類其實本身沒有init方法推沸,不能像對象一樣在init的時候賦值备绽。

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        // return an Int value here
        return 10;
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        // return an Int value here
        return 10;
    }
}

class SomeClass {
    static var computedTypeProperty: Int {
        // return an Int value here
        return 10;
    }
}

使用的時候可以println(SomeClass.computedT ypeProperty)醬紫即可。


Methods

在類里面使用property以及方法的時候鬓催,會默認認為是self.的肺素,所以如果你不加self也是可以的。唯一沖突的時候就是方法參數(shù)名和property名稱重復宇驾,這個時候方法參數(shù)名是優(yōu)先的倍靡,如果想refer to property需要加self的哦

Structures and enumerations值類型的屬性是不能改的,如果要必須在方法前加mutating课舍,在方法里面甚至改掉self都可以塌西。

struct Point2 {
    var x = 0.0, y = 0.0
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}

// self修改
enum TriStateSwitch {
    case Off, Low, High
    mutating func next() {
        switch self {
        case .Off:
            self = .Low
        case .Low:
            self = .High
        case .High:
            self = .Off
        }
    }
}

但是如果用let修飾一個struct他挎,仍舊是不可以調(diào)用這個struct的mutating的方法的:

let fixedPoint = Point(x: 3.0, y: 3.0) 
fixedPoint.moveByX(2.0, y: 3.0)
// this will report an error
  • 類方法對于class而言你可以通過在func之前聲明class來定義,對于枚舉和struct捡需,可以用static來聲明類方法办桨。在OC里面只可以給class定義類方法,swift里面就很隨意都可以~
class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}

類方法里面的self指的是類站辉,而非對象~ 在類方法里面可以引用類屬性呢撞,但是不可以引用對象屬性哦。


Subscripts

通過下標取和設(shè)置值是可以定義的:

subscript(index: Int) -> Int {
    get {
        // return an appropriate subscript value here
    }
    set(newValue) {
        // perform a suitable setting action here
    }
}

# 只讀
subscript(index: Int) -> Int {
    // return an appropriate subscript value here
}

舉個例子:

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier: 3)
print("six times three is \(threeTimesTable[6])")

dictionary的下標返回值是optional的饰剥,例如int?殊霞,因為不是所有key都有value的,可能這個key不存在啦捐川,而且可以通過將value設(shè)為nil來刪除這個key-value對

還可以定義多個參數(shù)的下標哦脓鹃,類似二維數(shù)據(jù)就可以通過多個參數(shù)取值:subscript(row: Int, column: Int) -> Double逸尖,然后就可以這樣取值啦matrix[0, 1]


Inheritance

swift木有一個類似OC里面的NSObject的通用基類古沥,所以如果不是繼承了別的類,可以不用聲明繼承~

繼承的聲明時醬紫的class SomeClass: SomeSuperclass娇跟,Unlike Objective-C, initializers are not inherited by default in Swift. swift里面的init是必須的岩齿,不會默認繼承父類的

插一句swift里面的description是醬紫的:

class SomeClass {
    var description:String {
        let keys =   ["access_token","uid","remind_in","screen_name","avatar_large"]
        return keys.description
    }
}

print(SomeClass().description)

如果是覆寫父類的方法屬性必須有override關(guān)鍵字,編譯時就會去check是不是覆寫了父類的方法苞俘,如果父類沒有這個方法會報錯的盹沈。

屬性繼承的時候如果同時提供了getter和setter就是讀寫屬性,如果只提供getter就是只讀屬性吃谣,繼承的時候可以把父類的只讀改為讀寫屬性乞封,但是不能把讀寫屬性限制為只讀哦

If you provide a setter as part of a property override, you must also provide a getter for that override. If you don’t want to modify the inherited property’s value within the overriding getter, you can simply pass through the inherited value by returning super.someProperty from the getter

如果屬性是let或者read-only,那么就不能增加observer岗憋,因為根本不會有set的過程肃晚。并且如果覆寫了setter也可以不用增加observer,因為在setter里面可以寫~

  • 如果你不想讓子類覆寫仔戈,可以用@final來修飾关串。@final var, @final func, @final class func, and @final subscript。如果用final修飾class监徘,那么這個class是不能有子類繼承的哦
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末晋修,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凰盔,更是在濱河造成了極大的恐慌墓卦,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件户敬,死亡現(xiàn)場離奇詭異落剪,居然都是意外死亡溅漾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門著榴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來添履,“玉大人,你說我怎么就攤上這事脑又∧弘剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵问麸,是天一觀的道長往衷。 經(jīng)常有香客問我,道長严卖,這世上最難降的妖魔是什么席舍? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮哮笆,結(jié)果婚禮上来颤,老公的妹妹穿的比我還像新娘。我一直安慰自己稠肘,他們只是感情好福铅,可當我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著项阴,像睡著了一般滑黔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上环揽,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天略荡,我揣著相機與錄音,去河邊找鬼歉胶。 笑死汛兜,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的跨扮。 我是一名探鬼主播序无,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼衡创!你這毒婦竟也來了帝嗡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤璃氢,失蹤者是張志新(化名)和其女友劉穎哟玷,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡巢寡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年喉脖,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片抑月。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡树叽,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出谦絮,到底是詐尸還是另有隱情题诵,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布层皱,位于F島的核電站性锭,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏叫胖。R本人自食惡果不足惜草冈,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望瓮增。 院中可真熱鬧怎棱,春花似錦、人聲如沸钉赁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽你踩。三九已至,卻和暖如春讳苦,著一層夾襖步出監(jiān)牢的瞬間带膜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工鸳谜, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留膝藕,地道東北人。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓咐扭,卻偏偏與公主長得像芭挽,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蝗肪,可洞房花燭夜當晚...
    茶點故事閱讀 43,486評論 2 348