swift5.5语法

1.swift3.0以后,去除了自增(++)和自减(--)的运算符,替代成了-=+=

 func TestDemo() {
        var num = 5
        while num > 0 {
            print("打印了了\(num)次")
            num -= 1
        }
    }

2.区间运算符 注意对应的符号,一定是3个点, 2个点的是半区间,字符串也能使用区间运算符,但是不能再for in中使用

  • 半区间运算符 1...3
  • 闭区间运算符 1..<3
  • 单侧(方向)区间:[...3] [3...]

3.区间类型

  let range: ClosedRange<Int>  = 1...3
  let range2: Range<Int> = 1..<3
  let range3: PartialRangeThrough<Int> = ...5

3.switch注意点

case default至少要有一条语句,如果不需要,加个break即可
如果能保证已处理所有情况,可以不必使用default

4.switch和enum的标准用法

  • enum虽然有其他简便写法,但是此种是最标准的
- 
public enum SelectedBarVerticalAlignment {
    case top
    case middle
    case bottom
}

switch selectedBarVerticalAlignment {
        case .top:
            selectedBarFrame.origin.y = 0
        case .middle:
            selectedBarFrame.origin.y = (frame.size.height - selectedBarHeight) / 2
        case .bottom:
            selectedBarFrame.origin.y = frame.size.height - selectedBarHeight
        }

枚举相关概念:
1.枚举成员可以使用相同类型的默认值预先对应, 这个值默认叫做原始值
2.如果枚举的原始值类型是Int String ,swift会自动分配原始值, 这个叫:隐式原始值
3.原始值不占用枚举变量的内存

5.swift中的访问控制关键字

  • private 私有访问控制 只允许当前类中调用
  • fileprivate(不常用) 其修饰的属性或者方法只能在当前的 Swift 源文件里可以访问
  • public修饰的属性或者方法可以在其他作用域被访问,但不能在override 和 继承方法中的 Extension 中被访问
  • open在override 和 继承方法中的 Extension 中可以被访问
    总结:原来 Swift 中有2种常用访问控制关键字(访问控制修饰符),分别为 private 和 public。而在 Swift 3.0+,又在原来的基础上新增了两种:fileprivate、open。它们可以看成是对 private 和 public 的进一步细分

6.空合并运算符(常用) ??

高级语法中的 两个问号?? : 意思是:如果数据不存在,则为??后面的值

var optionalInt: Int?
let result: Int = optionalInt ?? 10 result = 10

var optionalInt: Int? = 20
let result: Int = optionalInt ?? 10 result = 20

// if let 与 ??结合使用
let a: Int? = nil
let b: Int? = 2
if let c = a ?? b {
   print(c)
}

6.guide语句

读几遍:
guard 语句的条件为false, 就会执行大括号里面的代码
guard 语句的条件为true, 就会跳过guard语句
guard语句进行可选性绑定时,绑定的let var能在外层作用域中使用
总结: 判断条件不符合的高级写法,优化了OC的判断特性

guard <#condition#> else {
            <#statements#>
        }

7.结构体和类

吐槽:初学感觉类和结构体傻傻分不清(忽略) 精简分析一下:不一笔带过

结构体分析:

  • 在swift标准库中,绝大多数的公开类型都是结构体,而枚举和类只占很小一部分
  • 比如Bool, Int, Double, String, Array, Dictionary等常见类型都是结构体
  • 所有的结构体,编译器都会根绝情况为结构体自动生成多个初始化器,但是类是不会生成初始化器
  • 自定义初始化器时,编译器无法自动生成其他初始化器

类的分析:

  • 类中所有成员在定义时,指定了初始值,编译器才会为类生成无参的初始化器

类和结构体的本质区别:

  • 类是引用类型(指针类型),引用赋值给var, let或者函数传参是将内存地址拷贝一份,属于浅拷贝
  • 结构体和枚举是值类型,值类型赋值给var, let或者函数传参是将所有内容,产生了新的副本,属于深拷贝

注意:
初始化器的作用:保证所有的成员都有初始值
枚举,结构体,类都可以定义方法

8.属性

swift 中实例相关的属性可以分类2大类
存储属性:

  • 存储在实例的内存中
  • 结构体,类可以定义存储属性,枚举不可以
  • 延迟存储属性lazy:
    1.第一次用到的时候,属性才会初始化,lazy属性必须是var ,let必须在初始化完成之前拥有初始值
    2.如果多条线程同时第一次访问lazy属性,无法保证属性只被初始化一次
    计算属性:
  • 本质就是方法(函数)
  • 计算属性不占用实例内存
  • 定义计算属性只能用var,不能用let
 struct Circle {
        // 存储属性
        var radius: Double
        // 计算属性
        var diamater:Double {
            set {
                radius = newValue / 2
            }
            get {
                radius * 2
            }
        }
    }

9.属性观察器 willSet 和 didSet 现身

可以为非lazyvar存储属性设置属性观察器

  • willSet会传递新值,默认叫newValue
  • didSet会传递旧值,默认叫oldValue
  • 初始化器设置属性值不会触发
  • 在属性定义时设置初始值也不会触发
  • 可以应用在全局或局部变量身上
    struct Circle {
        // 存储属性
        var radius: Double {
            willSet {
                
            }
            didSet {
                
            }
        }
    }

10.inout关键字

inout的本质: 引用传递(地址传递)

11. 类型属性

  • 实例属性 :只能通过实例去访问,每个实例都有一份内存
  • 类型属性 :整个程序运行过程中,就只有1份内存(类似于全局变量)
    1.通过static定义类型属性, 也可以通过class定义, 整个程序运行过程中,就只有一份内存(类似于全局变量)
    2.存储类型属性必须设定初始值
    细节:
    存储属性分为:
  • 实例属性:
  • 类型属性:
    1.必须设定初始值(因为类型没有实例那样的init初始器来初始存储类型)
    2.类型属性默认是lazy,会在第一次使用的时候才初始化(就算被多个线程访问,也只会初始化一次)
    3.类型属性可以是let

12. 方法

枚举 结构体 类都可以定义实例方法和类方法

  • 实例方法:通过实例对象调用
  • 类型方法:通过类型调用,用static 和 class 关键字定义
  • self 在实例方法中代表是实例对象, 在类型中代表是类
  • mutating: 结构体和枚举是值类型, 值类型的属性不能被自身的实例方法修改, 如果要修改在fun关键字前加mutating
  • discardableResult 消除调用后返回值未被使用的警告

13.下标

下标是用于访问集合、列表或序列的成员元素的快捷方式。可以使用下标,设置和获取值,而不用单独的调用对应的存取
下标语法

subscript(index: Int) -> Int {
    get {
      // 返回一个适当的 Int 类型的值
    }

    set(newValue) {
      // 执行适当的赋值操作
    }
}

下标用法:

class Student: NSObject {

    var name = ""
    var age = 10
    var height = 170
    
    subscript(index:Int) -> AnyObject{
        switch index{
        case 0:
            return name as AnyObject
        case 1:
            return age as AnyObject
        case 2:
            return height as AnyObject
        default:
            return name as AnyObject
        }
    }
}

//调用
let stu = Student()
stu.name = "海王"
print(stu[0])  //海王
print(stu[1])  //10
print(stu[2])  //170

14.继承

  • 值类型不支持继承,只有类才可以继承
  • 子类可以重写父类的 方法 下标 属性 ,重写时加上关键字override
  • class修饰的类方法,下标,允许被子类重写
  • static修饰的类方法,下标,不允许被子类重写
  • 子类可以把父类属性重写为计算属性
  • 子类不可以把父类属性重写为存储属性
  • 只能重写var属性,不能重写let属性
  • 重写后的属性权限不能小于父类属性
  • final修饰的方法, 下标, 属性 不能被重写
  • final修饰的类不能被继承关系

15.初始化器

有两种:

  • 便利初始化器
  • 指定初始化器
    required修饰指定初始化器,表明所有子类都必须实现出初始化器,如果子类重写了requierd初始化器,也必须加上requierd,不用加override

属性观察器:
父类的属性在自己的初始化器中赋值不会触发属性观察期,但是在子类的初始化器中赋值会触发属性观察期

可失败初始化器(不常用):
类,结构体,枚举可以使用init?定义可失败初始化器

  • 如果初始化器调用一个可失败初始化器导致初始化失败,那么整个初始化过程都失败,并且之后的代码都停止执行
  • 可以用init!定义隐式解包的可失败初始化器

反初始化器

  • deinit叫做反初始化器,类似于OC中的dealloc方法
  • 当类的实例对象被销毁内存时,就会调用实例对象的deinit方法
  • 父类的deinit可以被子类继承
  • 子类的deinit执行完毕后会调用父类的deinit

16.可选链

使用可选值有时会让人感到有点笨拙,所有的解包和检查会变得如此繁重,以至于会让你想要丢几个感叹号上去强制解包,好让你能继续工作下去。但是请小心:如果你强制解包一个没有值的可选值,你的代码就崩了

func albumReleased(year: Int) -> String? {
    switch year {
    case 2006: return "Taylor Swift"
    case 2008: return "Fearless"
    case 2010: return "Speak Now"
    case 2012: return "Red"
    case 2014: return "1989"
    default: return nil
    }
}

let album = albumReleased(year: 2006)?.uppercased()
print("The album is \(album)")

  • 注意这里有个“问号”,这就是可选链:在“问号”后的所有代码,只会在“问号”前的代码有值时,才会运行。
  • Swift 将会从左到右检查它们,直到遇到一个 nil 后停止。如下
let album = albumReleased(year: 2006)?.someOptionalValue?.someOtherOptionalValue?.whatever

17.协议

协议可以定义属性,方法, 下标。
协议可以被类,结构体,枚举遵循

protocol YPPhotoCapture: class {
    
    // Public api
    func start(with previewView: UIView, completion: @escaping () -> Void)
    func stopCamera()
    func focus(on point: CGPoint)
    func zoom(began: Bool, scale: CGFloat)
    func tryToggleFlash()
    var hasFlash: Bool { get }
    var currentFlashMode: YPFlashMode { get }
    func flipCamera(completion: @escaping () -> Void)
    func shoot(completion: @escaping (Data) -> Void)
    var videoLayer: AVCaptureVideoPreviewLayer! { get set }
    var device: AVCaptureDevice? { get }
    
    // Used by Default extension
    var previewView: UIView! { get set }
    var isCaptureSessionSetup: Bool { get set }
    var isPreviewSetup: Bool { get set }
    var sessionQueue: DispatchQueue { get }
    var session: AVCaptureSession { get }
    var output: AVCaptureOutput { get }
    var deviceInput: AVCaptureDeviceInput? { get set }
    var initVideoZoomFactor: CGFloat { get set }
    func configure()
}
  • 协议不指定是否该属性应该是一个存储属性或者计算属性,它只指定所需的属性名称和读写类型。属性要求总是声明为变量属性,用var关键字做前缀

  • 要求该属性的读写权限(可读可写或者可读)

  • mutating关键字 : mutating关键字放在方法func关键字之前,表明该方法允许修改所属实例的任何属性

  • @escaping关键字:逃逸闭包

  • 协议SomeProtocol中不光可以声明方法/属性/下标,还可以声明构造器,但在Swift中,除了某些特殊情况外,构造器是不被子类继承的,所以SomeClass中虽然能够保证定义了协议要求的构造器,但不能保证SomeClass的子类中也定义了协议要求的构造器。所以我们需要在实现协议要求的构造器时,使用required关键字确保SomeClass的子类必须也得实现这个构造器。

  • Optional协议要求只有在你的协议被@objc属性标记时指定。
    即使你不与Objective-C交互,如果你希望指定optional要求,你仍然需要使用@objc标记你的协议。
    使用@objc标记的协议只能通过类调用

18.Any于AnyObject的区别

  • 两者都可以表示OC中的id 任意类型
  • AnyObject用于任何类(class)的实例,而Any可以用于表示任何类型,包括基本类型、值类型以及实例
  • 应该尽量多使用泛型少用Any,避免转换类型是发生的类型错误
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 229,517评论 6 539
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,087评论 3 423
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 177,521评论 0 382
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,493评论 1 316
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,207评论 6 410
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,603评论 1 325
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,624评论 3 444
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,813评论 0 289
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,364评论 1 335
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,110评论 3 356
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,305评论 1 371
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,874评论 5 362
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,532评论 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,953评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,209评论 1 291
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,033评论 3 396
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,268评论 2 375

推荐阅读更多精彩内容

  • 目录一、常量与变量二、数据类型三、特有的运算符四、流程控制语句 一、常量与变量 常量是指第一次赋值后,不能再次赋值...
    意一ineyee阅读 1,182评论 0 6
  • swift是Apple在2014年6月WWDC发布的全新编程语言,中文名和LOGO是雨燕,Swift是由Chris...
    coder_feng阅读 687评论 0 4
  • 目录 Swift 1.类型安全Swift 是一个类型安全(type safe)的语言。由于 Swift 是类型安全...
    勇敢的_心_阅读 390评论 0 1
  • 小视频 001--swift简史小视频 002--Playground体验 003--常量&变量 一、swift简...
    谦谦君子修罗刀阅读 6,977评论 8 66
  • YES 2014WWDC发布 常量和变量使用注意 在实际过程中,建议先定义常量,如果需要修改再改变为变量(更加安全...
    南冯阅读 566评论 0 0