Swift 学习的知识点

  1. 大数据: 可以插入 "_" 对数据进行分割 比如:100万 可以写成 1_00_0000

  2. 浮点型: 使用科学计数法: 1.2x10^3--->1.2e3

  3. 可以使用'_'忽略一些数值。

  4. print

(1)字符串的插值操作。

print("(x) * (y) = (z)");

(2)separator 分隔符 默认情况是一个空格 terminator默认情况是回车

5.注释可嵌套 : ///**/

  1. 求余运算:浮点型也可以。

7.repeat--while

  1. switch (可以是任意类型的值)

(1)case "a","A"{} 可以是多种情况并列书写。也可以 判断区间 case 1...90 case (a,b) 元组

(2)需要罗列出所有的可能情况

  1. break 可以跳出指定循环体:比如:

    使用给for循环命名的语法,执行break跳出的循环体。

    //x^4 - y^2 = 15*x*y;
    FindAnswer:for m in 1...300 {
        for n in 1...300 {
            if m*m*m*m - n*n == 15*n*m {
                print("m is \(m) , n is \(n)");
                break FindAnswer;
            }
        }
    }
  1. case where 使用,他可以使用在switch,for 语句中,在if中使用在swift3.x 中更换成了“,”.

  2. guard 的使用方法方式,用于边缘值的判断。
    /*
    如果条件不满足,就执行else
    */
    guard 条件 else {
    执行体
    }

  3. 字符串.count,基于unicode,所以每一个表情或者中文,都看作是一位。读取更加精准。

  4. 在Swift3.0 advancedBy使用以下代替:

let index = testName.index(testName.startIndex, offsetBy: 1)

14.删除t冗余字符。

let str = CharacterSet(charactersIn: "_ -"); //这里是删除多余的 "_-" 这两种符号。

tmpStr.trimmingCharacters(in: str);

  1. 可选型:强制解包(!),if let , "??"

解包: (1)if let 变量1=要解包的变量,let 变量2=要解包的变量,进一步条件限制比如:变量1=="404"

(2) 可选变量??"数值" <====>可选变量==nil?"数值":可选变量!;

(3)OPtional Chaining:尝试解包(?)比如: errorMessage?.uppercased();等价于 if let 解包。

(4)隐式可选型:let ageInt :String! = nil;可以不付初值,但是在使用的时候,一定要保证有值。

  1. indexOf ===> firstIndex(of: 3)或者 lastIndex(of:);//元素的位置index

  2. 忽略外部参数名,使用 "_"

  3. 参数传递:inout 应该写在参数类型的前面:比如:func swapOut ( _ num1:inout Int , _ num2:inout Int )

  4. 枚举类型的不同,枚举可以有数值型,关联类型,以及枚举可以遵守协议。

数值型: enum 枚举名称:数值类型 { case .枚举值类型 = 数值(RawValue)}

关联类型: enum 枚举类型 { case .枚举值(参数1,参数2,...)}; 如:调用的时两种类型

(1)case let .枚举值(参数1,参数2,...)

(2)case .枚举值(let 参数1,var 参数2,...) let var 可同时存在。

  1. 可选型也是一个枚举类型。

21.递归枚举类型 indirect enum 枚举类型。

22.类和其他的结构体、枚举类型的不同点:

(1)它内部的成员变量必须带有初始值,除了可选类型以外。

23.结构体或者枚举中声明方法时,需要在 func 前面 加上 mutating,

24.M_PI ----更换成了----> Double.pi

  1. "===" 判断 两个引用类型 是否指向了同一片内存区域。

26.延迟属性:lazy var 属性名称 : 属性类型 = { ... return 返回值}()

27.类方法直属于类,而不是类的实例变量。 需要在func 前面加上 static ,
同理,类属性也是,在var \ let 前面加上 static.

28.属性观察器:
注意:didSet willSet 在初始化的时候不会被调用,或者第一次 赋值的时候也不调用。
使用场景:再给一个变量 赋值前后,分别触发 wilSet didSet 并且 会分别 : 返回一个数值:newValue \ oldValue;

29.private 原本设计需要分文件处理在可以使得 private 私有属性生效,现在不需要了,仅仅是,写上 private 关键字 ,就可以生效。

30.final 表示 该类不能够拥有子类,也就是说,别的类不能即成该类。

31.当父类中声明了某一个属性后,子类也想声明该属性,则可以在声明时,使用 override 来修饰。用来覆盖父类中的方法或者属性。如果某一个父类中的属性或者方法不想被子类覆盖,可以使用final 进行修饰。
这就是重载。

  1. swift的两段式构造原则: 子类中的特殊属性,优先初始化,然后在使用父类的初始化方法,再去初始化共有属性,在子类函数中,使用到的父类的属性。如果想要使用某些属性的时,需要在super.init 方法之后使用self.属性进行调用,否则就会报错。
    (1)第一步:先初始化本类属性
    (2)第二步:在使用父类的初始化函数(super.init), 初始化父类属性
    (3)第三步:最后进行相关逻辑的操作,对相关属性的操作。

33.便利构造器: convenience. ---> 就是构造函数中,还调用另一个构造函数,此时外层的构造函数需要使用 convenience 修饰 表明是便利构造器

特点:
(1)一个构造函数,一定调用的它本身的另一个构造函数(指定的构造函数)

(2)便利构造函数 能够 调用 self. 某一个函数 ,而 普通的构造函数,才能够调用 super.

34.构造函数是以 init 开头的

  1. 父类构造函数的继承规则

(1)如果子类实现了父类的所有的指定构造函数(),则子类会自动的继承父类的所有的便利构造函数()。
(2)如果子类没有实现任何父类的指定构造函数(),则子类会自动继承父类的所有的指定构造函数以及便利构造函数()。

  1. 使用 required 表示必须被子类所实现的函数

特点:
(1)required 修饰的方法 在子类中,不需要使用 override 而是 使用 required 修饰。

  1. 文档注释

pragma mark --------------------文档注释--------------------

  1. swift 下标问题 Subscript 函数设置 角标问题: 参数可以任意类型的,形式:

///根据下标 获取 相应的数值 --> 设置成 数字角标 0,1,2

    subscript(index:Int)->Double?{
        
        get{
            switch index {
            case 0: return x;
            case 1: return h;
            case 2: return z;
            default:
                return nil;
            }
        }
        set{
            
            guard let newValue = newValue else { return }
            
            switch index {
            case 0: x = newValue;
            case 1: h = newValue;
            case 2: z = newValue;
            default:
                return ;
            }
        }
        
    }

//调用 表达
v[1] = 200;
v[1]
  1. assert 断言 , 错误 提示

  2. 运算符重载 语法 --> func 方法名() { return }

比如:运算符 重载

func + (left: Vector3 , right: Vector3) -> Vector3{
    return Vector3(x: left.x + right.x, h: left.h + right.h, z: left.z + right.z);
}

prefix 前缀 修饰符 postfix 后缀运算符

比如:
prefix func - (vector:Vector3)->Vector3{
    return Vector3(x:-vector.x,h:-vector.h,z:-vector.z);
}
  1. 自定义运算符 :

(1) 声明运算符

<1> 单目运算符声明 使用 operator 修饰

向前结合: prefix operator 自定义运算符; 向后结合: postfix operator 自定义运算符;

<2> 双目运算符声明 使用 infix operator 修饰

向前结合: prefix operator 自定义运算符; 向后结合: postfix operator 自定义运算符;

选择的字符范围:/ = - + ! * % < > & | ^ ~ 或者 unicode 码

<3> 定义运算符的优先等级以及向左或右结合属性

swift 3.0 之前 operator 自定义的运算符 { associativity left precedence 100} left 向左结合 100 优先等级数

swift 3.0 之后 使用 precedencegroup 创建一个 优先等级组 :

precedencegroup 优先级组名称 {
higherThan: 较低优先级组的名称
lowerThan: 较高优先级组的名称
associativity: 结合性
assignment: 赋值性
}

比如:

precedencegroup AddPrecedence {
    associativity : left
    higherThan:MultiplicationPrecedence  --> 来源于文档中优先等级表。
}
infix operator ** : AddPrecedence
func **(x: Double, p:Double) -> Double{
    return pow(x,p)
}

<4> 优先级分类 : AdditionPrecedence(+ 、-), MultiplicationPrecedence(* 、 /)

  1. extension 可以为类或结构体 添加方法、属性(不能是存储类型的属性,需要是,计算属性)、添加的必须是便利的构造函数,不能是指定的构造函数 语法: extension 要扩展的类 {}

计算类型的属性:语法: 类型 属性名称 {get{return 数据} set{设置数据的值}} 、也可以扩展下标 :使用subscriptions , 也可以给系统的标准库添加扩展。

  1. Nested Type 嵌套类型 : 比如为某一个类 定义自己特有的枚举值,而 这个枚举 类型 就是一个嵌套类型 。

形如:Rectangle.VertText.LeftBottom,String.Index

  1. 创建区间范围 : 从几到几 步长 多少 比如: 表示 2 ~ 20 步长 为 2 的区间

闭区间 : stride(from: 2, through: 20, by: 2)
开区间 : stride(from: 2, to: 20, by: 2)

之前:

开区间:2.stride(to 20, by: 2);
闭区间:2.stride(through 20, by: 2);

  1. 给 UIColor 添加扩展 支持 16 进制 表示 色值

  2. 泛型函数 语法 : func 函数名 <T> (参数名:T){} 其中 T 可以是任意命名 也就是说 func 函数名 <Ting> (参数名:Ting){} 也可以。

    泛型类型 语法 : 多个 泛型 时, 需要使用 ',' 隔开 比如: <T1,T2,...>

    两个泛型 的 结构体()

    struct Pair<T1,T2>{
        var a:T1;
        var b:T2;
    }
    let pair = Pair<Int,String>(a:1,b:"黑猫警长");
  1. 协议protocol 中 只写方法的声明 属性需要 指定 它的访问权限 比如是 只读,可读可写 语法 :名称 : 类型 { get 或者 set 或者 get set }

    也可以进行声明 构造函数 当声明构造函数后,应该在遵循该协议的类中,将该构造函数 设定成 必须实现 的函数 ,也就是 使用 required 修饰 构造函数。

(1) 让类遵循协议: var 类型 : 协议类型

(2) associatedtype 相当于类中的别名,在协议中使用该修饰关键字 来声明别名,类中 使用 typealias 别名 = 原始名称

(3) 场景描述:associatedtype 当有多个的类遵守同一个协议 ,并且 只有属性的类型不同时,也就是为不同类型的不同类型,设置统一的别名。 我们 可以通过 associatedtype 为 协议 定义 关联类型,让其在类的实现中,为该类型 关联不同的类型。
var weigth :WeightType{get};

代码如下: 在协议中, associatedtype 关联类型_A 在 类的实现中, typealias 关联类型_A = 要设定的类型; 缺一不可。

protocol WeightCaculable{
    associatedtype WeightType;  //同一个别名 WeightType
}

class iPhone7 :WeightCaculable{
    typealias WeightType = Double; //关联的 Double 类型
    var weigth: WeightType{
        return 0.01124;
    }
}

class Ship :WeightCaculable{
    typealias WeightType = Int; //关联的 Int 类型 
    var weigth: WeightType;
    init(weigth:WeightType) {
        self.weigth = weigth;
    }
}
  1. 协议 和 类 的混合使用 父类 要放在 协议的前面 也就是 语法: class 类名 : 父类名称 , 协议名称

  2. swift 标准库中的常用的协议:

(1)Equatable --> 让类或者结构体 遵循此协议后,可以对任意类型的进行 == != 之间的比较。

(2)Comparable --> 让类或者结构体 遵循此协议后,需要实现协议中的 "<" 方法重载 可以对任意类型的进行 == != 之间的比较,

同时,可以在重载实现 < > >= <= 中任意一个就可以使用其他的三种,进行比较。

同时,可以调用的该类型的数组,进行sort排序:比如:var JiLuS = [JiLuA,JiLuB,JiLuC,JiLuD]; JiLuS.sort();

//(3)BooleanType --改成了--> ExpressibleByBooleanLiteral ,告诉编译器,某一个类型,当成是Bool 类型

50.重点类型() 面向协议编程 : 对自定义以及系统类协议 也可以进行扩展。

场景描述: 一个协议 被多个类遵守,并且 协议中的方法,在不同类型中有着相同的实现逻辑,这时,我们可以通过对协议进行扩展,将不同类中的协议方法或者属性,在协议的扩展中 添加默认() 实现。

(1)特点:

(1)在扩展的实现,是 默认实现 ,我们可以在 不同类型,更改相应的属性值以及方法实现,来覆盖 扩展中的实现。

(2)协议聚合 ---> 让类的对象 遵从多个协议 使用 & 。 swift2 : protocol <Prizable , CustomStringConvertible> ---> swift3: Prizable & CustomStringConvertible

比如 : func award(one: Prizable & CustomStringConvertible)  相应的类 需要遵从相同的协议。

(3) 泛型的约束 :就是给泛型添加一定的约束条件 比如说: 让其遵守某个协议:<T:协议名称 & 协议名称>

51.可选的协议方法:

(1)需要在 protocol 前面添加 @objc

(2)在 可选的协议方法或属性前面 添加 @objc optional

(3)要求的 遵循该 协议的对象 必须是 Object--类 或者 继承于 Object--类;

(4)被修饰的方法变成了 可选的类型 所以在使用的时候要对其进行解包的操作:比如:delegate.turnEnd?() 或者使用 if let 的方法解包

  1. 断言的几种方式:

(1)assert()

(2)assertionFailure(<#T##message: String##String#>)

(3)assertionFailure()

(4)fatalError()

(5)fatalError(<#T##message: String##String#>)

(6)do { try } catch {} 使用规则:

<1> 对于函数声明时,声明成可抛异常的函数 : func 函数名称 () throws ->  返回值 或者 func 函数名称 () throws

<2> 函数实现中 使用 throw 抛出异常  throw 但是 该异常 要是Error类型 或者 继承于 Error的类型。比如:

enum ErrorType:Error , CustomStringConvertible {
    case NoEnoughMoneyError(Int)
    case NoGoodsError
    case UnKnowError
    
    var description: String{
        switch self {
        case .NoEnoughMoneyError(let price):
            return ("Not Enough Money. " + String(price) + " :Yuan needed");
        case .NoGoodsError :
            return ("No Goods");
        case .UnKnowError :
            return ("Unknow Error");
        }
    }
}

<3> 调用时,不能按照普通函数那样调用,要使用try进行修饰,try 表示尝试 忽略函数的异常, try? ---> 尝试 忽略; try! --> 表示 在确认该函数 没有异常情况的条件下,使用。
<4> do catch 就是针对 <3> 中的调用结果的进一步处理。

    do {

        myMoney = try vendingMahine.vend(itemName: "Mineral Juice", money: myMoney);
        print(myMoney,"Yuan left");

    } catch let error as VendingMachine.ErrorType { //类似强制解包处理,类型转换 ,转换成功,就进行打印错误信息。
    
        print(error);

    } catch {

        print("Error occured during vending."); // 所有情况都为匹配到该错误时,才会的走该内容!

     }

     对于单个的错误情况,可以使用 if - let 的方式进行处理

    if let leftMoney = try? vendingMahine.vend(itemName: "Mineral Juice", money: myMoney){
        //未发生异常:
        print(leftMoney);
    }else{
        //Error Handling 异常处理
    }

(7) 控制转移 defer 就是在一个作用于 结束的时候,调用,同时,如果一个作用域中,有多个defer的时候,先编译的后执行。 通常使用在错误提醒中。

  1. 内存管理

(1)weak 使用的方法:所修饰的量应该是 var 类型可变的 二是 可选类型。

(2)unowned 使用的方法:只能用来修饰类,不能修饰函数, 主要用来解决 weak 不能对 常量 不可选类型的 弱引用。 所修饰的量 可以修饰 可选类型. 同时,不能 对 函数进行修饰。

(3)闭包中的强引用:可以使用隐式可选型,就是说,在初始化的时候,有一段时间可以为空,在后续的过程中,会给该变量赋初值。语法: var 名称:类型 !

(4)Closure 的 强引用循环问题。 使用闭包列表 语法 [unowned self] 使用 unowned 或者 weak 将 self 变成 弱引用。

(5)self 将 self 存储到 self 中 需要使用 反单引号 引用 即 self = self .

/***********************闭包中 强引用 的 解决方案*********************************/

/*
 unowned 的 写法
 
 temperatureChange = { [unowned  self] newTemprature in
 
       if abs(newTemprature - self.temperature) >= 10 {
 
           print("It's not healthy to do it!");
 
       }else{
 
           self.temperature = newTemprature;
 
           print("New temperate \(self.temperature) is set!");
       }
  }
 
 */

/* weak 的 写法 */
temperatureChange = { [weak  self] newTemprature in
    
    if let `self` = self {
        
        if abs(newTemprature - self.temperature) >= 10 {
            
            print("It's not healthy to do it!");
            
        }else{
            
            self.temperature = newTemprature;
            
            print("New temperate \(self.temperature) is set!");
            
        }
        
    }
    
}
  1. weak && unowned 只能用在修饰类,不能修饰函数()

  2. 类型检查 使用 is 判断是否为同一类型,类型强制转换 使用 as 关键字: as? 尝试转换 , as! 强制转换。

  3. NSObject/AnyObject/Any

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

推荐阅读更多精彩内容