swift一些关键字的理解

1.typealias

//声明一个闭包类型 AddBlock

typealias AddBlock = (Int,Int)->(Int);

class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
let add:AddBlock = {
(a,b) in
return a + b;
}

let result = add(1100, 200);
print("result=(result)");
} }

2.escaping

逃逸闭包一般用于异步函数的回调,比如网络请求成功的回调和失败的回调。语法:在函数的闭包行参前加关键字“@escaping” ((Any?)->(Void))?,也可以表示网络请求成功的回调,不过后面需带“?”,这代表闭包可选类,这并不是闭包类型的,两者对比如下:

可选闭包

func requestData(urlString:String,succeed: ((Any?)->(Void))?,failure:((Any?)->(Void))?){}

逃逸闭包

func requestData(urlString:String,succeed: @escaping (Any?)->(Void),failure:@escaping (Any?)->(Void)){}

注意

如果是在闭包内部调用控制器,那么必须显示的写self。防止闭包带来的循环引用的问题

如何解决闭包的循环引用, 同样有三种方式:

使用weak修饰变量, 打破强引用, 因为使用weak修饰的变量有一次变成nil的机会

使用[weak self] 修饰闭包原理跟__weak类似, 这样在闭包中使用self, 就是弱引用

使用[unowned self ] 修饰闭包, 跟__unsafe_unretained类似, 不安全

eg:
// 解决方式一: weak
weak var weakSelf = self
loadData { (dataString) -> () in
print("(dataString) (weakSelf?.view)")
}
//解决方式二: 在swift中 有特殊的写法 ,跟OC __weak 相似 [weak self]
loadData { [weak self] (dataString) -> () in

    //以后在闭包中中 使用self 都是若引用的
    print("\(dataString) \(self?.view)")
}

//解决方式三: [unowned self] 跟 _unsafe_unretained 类似 不推荐使用
loadData { [unowned self] (dataString) -> () in
print("(dataString) (self.view)")
}
}
3.两个访问关键字介绍(fileprivate、open)

flieprivate

fileprivate 其实就是过去的 private。其修饰的属性或者方法只能在当前的 Swift 源文件里可以访问。即在同一个文件中,所有的 fileprivate 方法属性都是可以访问到的。

class A {

fileprivate func test(){

    print("this is fileprivate func!")
 } 

}

class B:A {
func show(){
test()
}
}
而private现在变为了真正的私有访问控制。就是说不管在不在同一个文件中,用private修饰的方法也不可以被代码域之外的地方访问。

class A {
private func printA(){
print("A")
}
}
class B:A {
func printB(){
printA()
}
}
上面的实例是我们使用private方法定义一个父类A的成员方法,但是当继承该类的子类调用该方法时将会报错

open

过去public有两个作用:

修饰的属性或者方法可以在其他作用域被访问;
修饰的属性或者方法可以在其他作用域被继承或重载override。
但这样就会有问题,为了安全,我们可能希望某个类或属性能够被外部访问,但又不想其被继承或修改。如果将其标记成final后又会造成任何地方都不能被override。比如对lib设计者来说,他希望的结果是在module内可以被override,而被import 到外部后不能被override。 现在新添加的open起的就是原来public的作用。而现在的public表示在其他module中不可以被override和继承,而在module内可以被 override和继承

5种修饰符访问权限排序

从高到低排序如下:

open> public > interal > fileprivate > private
4.Designated,Convenience 和 Required

在 Objective-C 中,init 方法是非常不安全的:没有人能保证 init 只被调用一次,也没有人保证在初始化方法调用以后实例的各个变量都完成初始化,甚至如果在初始化里使用属性进行设置的话,还可能会造成各种问题,虽然 Apple 也明确说明了不应该在 init 中使用属性来访问,但是这并不是编译器强制的,因此还是会有很多开发者犯这样的错误。

所以 Swift 有了超级严格的初始化方法。一方面,Swift 强化了 designated 初始化方法的地位。Swift 中不加修饰的 init 方法都需要在方法中保证所有非 Optional 的实例变量被赋值初始化,而在子类中也强制 (显式或者隐式地) 调用 super 版本的 designated 初始化,所以无论如何走何种路径,被初始化的对象总是可以完成完整的初始化的。

class ClassA {
let numA: Int
init(num: Int) {
numA = num
}
}

class ClassB: ClassA {
let numB: Int
override init(num: Int) {
numB = num + 1
super.init(num: num)
}
}
在上面的示例代码中,注意在 init 里我们可以对 let 的实例常量进行赋值,这是初始化方法的重要特点。在 Swift 中 let 声明的值是常量,无法被写入赋值,这对于构建线程安全的 API 十分有用。而因为 Swift 的 init 只可能被调用一次,因此在 init 中我们可以为常量进行赋值,而不会引起任何线程安全的问题。

与 designated 初始化方法对应的是在 init 前加上 convenience 关键字的初始化方法。这类方法是 Swift 初始化方法中的 “二等公民”,只作为补充和提供使用上的方便。所有的 convenience 初始化方法都必须调用同一个类中的 designated 初始化完成设置,另外 convenience 的初始化方法是不能被子类重写或者是从子类中以 super 的方式被调用的。

class ClassA {
let numA: Int
init(num: Int) {
numA = num
}

convenience init(bigNum: Bool) {
self.init(num: bigNum ? 10000 : 1)
}
}

class ClassB: ClassA {
let numB: Int
override init(num: Int) {
numB = num + 1
super.init(num: num)
}
}
只要在子类中实现重写了父类 convenience 方法所需要的 init 方法的话,我们在子类中就也可以使用父类的 convenience 初始化方法了。比如在上面的代码中,我们在 ClassB 里实现了 init(num: Int) 的重写。这样,即使在 ClassB 中没有 bigNum 版本的 convenience init(bigNum: Bool),我们仍然还是可以用这个方法来完成子类初始化:

let anObj = ClassB(bigNum: true) anObj.numA //10000 anObj.numB //10001

因此进行一下总结,可以看到初始化方法永远遵循以下两个原则:

初始化路径必须保证对象完全初始化,这可以通过调用本类型的 designated 初始化方法来得到保证;
子类的 designated 初始化方法必须调用父类的 designated 方法,以保证父类也完成初始化。
对于某些我们希望子类中一定实现的 designated 初始化方法,我们可以通过添加 required 关键字进行限制,强制子类对这个方法重写实现。这样做的最大的好处是可以保证依赖于某个 designated 初始化方法的 convenience 一直可以被使用。一个现成的例子就是上面的 init(bigNum: Bool):如果我们希望这个初始化方法对于子类一定可用,那么应当将 init(num: Int) 声明为必须,这样我们在子类中调用 init(bigNum: Bool) 时就始终能够找到一条完全初始化的路径了:

class ClassA {
let numA: Int
required init(num:Int) {
numA = num
}
convenience init(bigNum: Bool) {
self.init(num: bigNum ? 10000 : 1)
}
}
class ClassB:ClassA {
let numB: Int
required init(num: Int) {
numB = num + 1
super.init(num: num)
}
}
另外需要说明的是,其实不仅仅是对 designated 初始化方法,对于 convenience 的初始化方法,我们也可以加上 required 以确保子类对其进行实现。这在要求子类不直接使用父类中的 convenience 初始化方法时会非常有帮助。

4.final

可以通过把方法,属性或下标标记为final来防止它们被重写,只需要在声明关键字前加上final修饰符即可(例如:final var,final func,final class func,以及final subscript)。如果你重写了final方法,属性或下标,在编译时会报错。

5.static和class的区别

在方法的func关键字之前加上关键字static或者class都可以用于指定类方法. 不同的是用class关键字指定的类方法可以被子类重写, 如下:

override class func work() {
print("Teacher: University Teacher")
}
但是用static关键字指定的类方法是不能被子类重写的, 根据报错信息: Class method overrides a 'final' class method. 我们可以知道被static指定的类方法包含final关键字的特性--防止被重写.

这是我自己总结的,如有不对,望指出

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350

推荐阅读更多精彩内容

  • 20- 枚举,枚举原始值,枚举相关值,switch提取枚举关联值 Swift枚举: Swift中的枚举比OC中的枚...
    iOS_恒仔阅读 2,256评论 1 6
  • 123.继承 一个类可以从另外一个类继承方法,属性和其他特征。当一个类继承另外一个类时, 继承类叫子类, 被继承的...
    无沣阅读 1,385评论 2 4
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,599评论 18 399
  • 很高兴能参加上周日由冯江兰老师主持的:“儿童绘画看心理”沙龙活动。活动开始,首先老师通过一首欢快的音乐让家长和...
    东芝亲子读书阅读 898评论 0 0
  • 烟火 窗外,一场烟花绽放, 星月无迹, 烟花盛放比昙花还短, 只在刹那间。 在她们期待的眼眸里, 短暂的美丽反而永...
    宫尘阅读 282评论 0 3