-
大数据: 可以插入 "_" 对数据进行分割 比如:100万 可以写成 1_00_0000
-
浮点型: 使用科学计数法: 1.2x10^3--->1.2e3
-
可以使用'_'忽略一些数值。
-
print
(1)字符串的插值操作。
print("(x) * (y) = (z)");
(2)separator 分隔符 默认情况是一个空格 terminator默认情况是回车
5.注释可嵌套 : ///**/
- 求余运算:浮点型也可以。
7.repeat--while
- switch (可以是任意类型的值)
(1)case "a","A"{} 可以是多种情况并列书写。也可以 判断区间 case 1...90 case (a,b) 元组
(2)需要罗列出所有的可能情况
-
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;
}
}
}
-
case where 使用,他可以使用在switch,for 语句中,在if中使用在swift3.x 中更换成了“,”.
-
guard 的使用方法方式,用于边缘值的判断。
/*
如果条件不满足,就执行else
*/
guard 条件 else {
执行体
} -
字符串.count,基于unicode,所以每一个表情或者中文,都看作是一位。读取更加精准。
-
在Swift3.0 advancedBy使用以下代替:
let index = testName.index(testName.startIndex, offsetBy: 1)
14.删除t冗余字符。
let str = CharacterSet(charactersIn: "_ -"); //这里是删除多余的 "_-" 这两种符号。
tmpStr.trimmingCharacters(in: str);
- 可选型:强制解包(!),if let , "??"
解包: (1)if let 变量1=要解包的变量,let 变量2=要解包的变量,进一步条件限制比如:变量1=="404"
(2) 可选变量??"数值" <====>可选变量==nil?"数值":可选变量!;
(3)OPtional Chaining:尝试解包(?)比如: errorMessage?.uppercased();等价于 if let 解包。
(4)隐式可选型:let ageInt :String! = nil;可以不付初值,但是在使用的时候,一定要保证有值。
-
indexOf ===> firstIndex(of: 3)或者 lastIndex(of:);//元素的位置index
-
忽略外部参数名,使用 "_"
-
参数传递:inout 应该写在参数类型的前面:比如:func swapOut ( _ num1:inout Int , _ num2:inout Int )
-
枚举类型的不同,枚举可以有数值型,关联类型,以及枚举可以遵守协议。
数值型: enum 枚举名称:数值类型 { case .枚举值类型 = 数值(RawValue)}
关联类型: enum 枚举类型 { case .枚举值(参数1,参数2,...)}; 如:调用的时两种类型
(1)case let .枚举值(参数1,参数2,...)
(2)case .枚举值(let 参数1,var 参数2,...) let var 可同时存在。
- 可选型也是一个枚举类型。
21.递归枚举类型 indirect enum 枚举类型。
22.类和其他的结构体、枚举类型的不同点:
(1)它内部的成员变量必须带有初始值,除了可选类型以外。
23.结构体或者枚举中声明方法时,需要在 func 前面 加上 mutating,
24.M_PI ----更换成了----> Double.pi
- "===" 判断 两个引用类型 是否指向了同一片内存区域。
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 进行修饰。
这就是重载。
- swift的两段式构造原则: 子类中的特殊属性,优先初始化,然后在使用父类的初始化方法,再去初始化共有属性,在子类函数中,使用到的父类的属性。如果想要使用某些属性的时,需要在super.init 方法之后使用self.属性进行调用,否则就会报错。
(1)第一步:先初始化本类属性
(2)第二步:在使用父类的初始化函数(super.init), 初始化父类属性
(3)第三步:最后进行相关逻辑的操作,对相关属性的操作。
33.便利构造器: convenience. ---> 就是构造函数中,还调用另一个构造函数,此时外层的构造函数需要使用 convenience 修饰 表明是便利构造器
特点:
(1)一个构造函数,一定调用的它本身的另一个构造函数(指定的构造函数)
(2)便利构造函数 能够 调用 self. 某一个函数 ,而 普通的构造函数,才能够调用 super.
34.构造函数是以 init 开头的
- 父类构造函数的继承规则
(1)如果子类实现了父类的所有的指定构造函数(),则子类会自动的继承父类的所有的便利构造函数()。
(2)如果子类没有实现任何父类的指定构造函数(),则子类会自动继承父类的所有的指定构造函数以及便利构造函数()。
- 使用 required 表示必须被子类所实现的函数
特点:
(1)required 修饰的方法 在子类中,不需要使用 override 而是 使用 required 修饰。
- 文档注释
pragma mark --------------------文档注释--------------------
- 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]
-
assert 断言 , 错误 提示
-
运算符重载 语法 --> 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> 单目运算符声明 使用 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(* 、 /)
- extension 可以为类或结构体 添加方法、属性(不能是存储类型的属性,需要是,计算属性)、添加的必须是便利的构造函数,不能是指定的构造函数 语法: extension 要扩展的类 {}
计算类型的属性:语法: 类型 属性名称 {get{return 数据} set{设置数据的值}} 、也可以扩展下标 :使用subscriptions , 也可以给系统的标准库添加扩展。
- Nested Type 嵌套类型 : 比如为某一个类 定义自己特有的枚举值,而 这个枚举 类型 就是一个嵌套类型 。
形如:Rectangle.VertText.LeftBottom,String.Index
- 创建区间范围 : 从几到几 步长 多少 比如: 表示 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);
-
给 UIColor 添加扩展 支持 16 进制 表示 色值
-
泛型函数 语法 : 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:"黑猫警长");
-
协议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;
}
}
-
协议 和 类 的混合使用 父类 要放在 协议的前面 也就是 语法: class 类名 : 父类名称 , 协议名称
-
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)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)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!");
}
}
}
-
weak && unowned 只能用在修饰类,不能修饰函数()
-
类型检查 使用 is 判断是否为同一类型,类型强制转换 使用 as 关键字: as? 尝试转换 , as! 强制转换。
-
NSObject/AnyObject/Any
网友评论