Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

iOS学习笔记(三)基础篇(下) #9

Open
xiwenAndlejian opened this issue Oct 17, 2018 · 0 comments
Open

iOS学习笔记(三)基础篇(下) #9

xiwenAndlejian opened this issue Oct 17, 2018 · 0 comments

Comments

@xiwenAndlejian
Copy link
Owner

iOS学习笔记(三)基础篇(下)

学习笔记来自https://www.hackingwithswift.com/read/0

环境版本:

  • iOS12
  • Swift4.2

属性

结构和类(统称为“类型”)可以有自己的变量和常量,这些属性被称为属性。

struct Person {
    var clothes: String
    var shoes: String
    
    func describe() {
        print("I like wearing \(clothes) with \(shoes)")
    }
}

let taylor = Person(clothes: "T-shirts", shoes: "sneakers")
let other = Person(clothes: "short skirts", shoes: "high heels")
taylor.describe()// 输出:I like wearing T-shirts with sneakers
other.describe()// 输出:I like wearing short skirts with high heels

在方法中使用类型的属性时,将自动使用属于当前对象的值。

property observers

Swift可以观察属性值,在属性即将被修改或已更改时调用代码。
两种属性观察者:

  • willSet:在属性更改之前调用。可以通过newValue获取新属性值
  • didSet:在属性更改之后调用。可以通过oldValue获取之前的值
    code:
struct Person {
    var clothes: String {
        willSet {
            updateUI(msg: "I'm changing from \(clothes) to \(newValue)")
        }

        didSet {
            updateUI(msg: "I just changed from \(oldValue) to \(clothes)")
        }
    }
}

func updateUI(msg: String) {
    print(msg)
}

var taylor = Person(clothes: "T-shirts")// 输出:I'm changing from T-shirts to short skirts
taylor.clothes = "short skirts"// 输出:I just changed from T-shirts to short skirts

computed properties

计算属性。

struct Person {
    var age: Int

    var ageInDogYears: Int {
        get {
            return age * 7
        }
    }
    
    // 仅用于读取数据则可以省略`get{}`
    var ageInDogYears2: Int {
            return age * 7
    }
}

var fan = Person(age: 25)
print(fan.ageInDogYears)// 输出:175

静态的属性和方法

关键字:static
调用:类型名.属性/方法名()

struct TaylorFan {
    static var favoriteSong = "Look What You Made Me Do"

    var name: String
    var age: Int
}

//let fan = TaylorFan(name: "James", age: 25)
print(TaylorFan.favoriteSong)

存放全局信息

可以用来存放全局的用户信息

// 声明
struct UserToken {
    static var currentUserToken: UserToken?
    
    var username: String
    var token: String
    ...
    
    init(username: String, token: String) {
        self.username = username
        self.token = token
    }
}

// 用户登录时进行赋值
UserToken.currentUserToken = UserToken(username: "绿谷", token: "secret")
// 调用
print(UserToken.currentUserToken!.username)
// 别忘了登出记得清空
UserToken.currentUserToken = UserToken(username: "", token: "")

这样就可以在多个视图控制器中访问

access control

  • Public:任何人都可以读取
  • Internal:只有你自己的swift代码才能读写此属性
  • File private:类型相同的文件才能读写该属性
  • Private:最高的限制,表明此属性只能在此类型的内部方法或它的扩展中使用。
class TaylorFan {
    private var name: String!
    fileprivate var filename: String!
}

多态性和类型转换

类可以互相继承,这意味着一个类实际上是另一个类的超集:类B具有A所具有的所有东西,还包括一些额外的。同时也可以将B看做B类或者A类。

class Album {
    var name: String

    init(name: String) {
        self.name = name
    }
}

class StudioAlbum: Album {
    var studio: String

    init(name: String, studio: String) {
        self.studio = studio
        super.init(name: name)
    }
}

class LiveAlbum: Album {
    var location: String

    init(name: String, location: String) {
        self.location = location
        super.init(name: name)
    }
}

var taylorSwift = StudioAlbum(name: "Taylor Swift", studio: "The Castles Studios")
var fearless = StudioAlbum(name: "Speak Now", studio: "Aimeeland Studio")
var iTunesLive = LiveAlbum(name: "iTunes Live from SoHo", location: "New York")

// StudioAlbum & LiveAlbum 都可以被看做是 Album 类
var allAlbums: [Album] = [taylorSwift, fearless, iTunesLive]

多态

class Album {
    var name: String

    init(name: String) {
        self.name = name
    }

    func getPerformance() -> String {
        return "The album \(name) sold lots"
    }
}

class StudioAlbum: Album {
    var studio: String

    init(name: String, studio: String) {
        self.studio = studio
        super.init(name: name)
    }

    override func getPerformance() -> String {
        return "The studio album \(name) sold lots"
    }
}

class LiveAlbum: Album {
    var location: String

    init(name: String, location: String) {
        self.location = location
        super.init(name: name)
    }

    override func getPerformance() -> String {
        return "The live album \(name) sold lots"
    }
}

var taylorSwift = StudioAlbum(name: "Taylor Swift", studio: "The Castles Studios")
var fearless = StudioAlbum(name: "Speak Now", studio: "Aimeeland Studio")
var iTunesLive = LiveAlbum(name: "iTunes Live from SoHo", location: "New York")

var allAlbums: [Album] = [taylorSwift, fearless, iTunesLive]

for album in allAlbums {
    print(album.getPerformance())
}
// 依次输出:
// The studio album Taylor Swift sold lots
// The studio album Speak Now sold lots
// The live album iTunes Live from SoHo sold lots

向下转型 as

Swift的类型转换

  • as:类型转换,比较少用(没有处理异常)
  • as?:可能会失败的类型转换
  • as!:一定能转换,如果出错,则程序会崩溃
for album in allAlbums {
    print(album.getPerformance())
    // 通过类型转换,来调用额外的属性
    if let studioAlbum = album as? StudioAlbum {
        print(studioAlbum.studio)
    } else if let liveAlbum = album as? LiveAlbum {
        print(liveAlbum.location)
    }
}

当Swift不知道对象的类型时,类型转换很有用。但当Swift明白对象的实际类型时,就不能强制转换为不相关的类型。

let number = 5
let text = number as! String // ❎:无法转换

let text = String(number) // ✅:可以使用
print(text)

闭包

闭包可以被认为是保存代码的变量。
闭包本身就是一种数据类型:可以将闭包作为参数传递或者将其存储为属性。

let vw = UIView()

UIView.animate(withDuration: 0.5, animations: {
    vw.alpha = 0
})

// 尾随闭包
// 方法的最后一个参数采用闭包,则可以取消该参数
UIView.animate(withDuration: 0.5) {
    vw.alpha = 0
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant