1.Swift 中的屬性必須默認有值,要不然就設(shè)置可空? ,否則編譯不過
2.能不寫self就不寫,但是閉包里面要寫,因為不知道何時執(zhí)行這個閉包
3.懶加載,lazy關(guān)鍵字 ?,閉包后面已經(jīng)要加上() 。必須是var, swift 中的懶加載和oc中的懶加載不同,不會因為 置值為nil操作而執(zhí)行懶加載中閉包。也就是說,懶加載 無論在什么情況下都是最多只執(zhí)行一次。
4.如果閉包用于懶加載,那么包括in 之前的括號什么的可以省略,因為懶加載沒有閉包的輸入?yún)?shù),并且可以推斷返回類型
lazy var dataSource:[String] = {
print("加載")
return ["23","34","45","56"]
}()
5.出現(xiàn)switch condition evaluates to a constant 吧變量放到函數(shù)外面
不支持++ , -- 等運算符,但是 -= ,+= 還是支持的
swift3 。函數(shù)inout 用于修飾參數(shù)類型,而不是修飾參數(shù),位置放到參數(shù)雙引號之后,類型之前
6.可選類型 ? ;var name:String? = "tom" ? ? name是可選類型,可以是String,可以是nil (nil本身也是一種類型),如果name不是可選類型,那么name = nil 編譯失敗
可選類型是不能直接使用的,因為不知道什么時候變成nil,有可能導(dǎo)致crash。如果可選類型在使用的時候不解包,最明顯的特征就是log會有option字樣,解包之后就不會出現(xiàn)
1??強制解包,不安全,使用前提 name!,使用前提必須確定name不會是nil,如果name是nil,強制解包會crash
2??判空解包 ?if name != nil {print(name!)} 使用規(guī)則,在非空的作用域內(nèi)使用name的時候,也是要強制解包的 +!
3??可選鏈式調(diào)用,p.name = p.name!.uppercaseString? 如果p.name是nil ,那么crash
p.name = p.name?.uppercaseString ?,如果沒有p.name 是nil ,那么直接返回nil。
可選鏈式 p.property1?.property2?.property3?....,一層層解包,只要有任意一個節(jié)點是nil。立刻返回nil
4??空合運算符? 作用解包之后,把解包之后的值賦值另外一個變量let name = p.name ?? "noname"
7.結(jié)構(gòu)體, 結(jié)構(gòu)體可有屬性和函數(shù),var myStruct = MyStruct()? ? 結(jié)構(gòu)體中的函數(shù)默認對屬性沒有寫權(quán)限,mutating fun setPoitn ... mutating 關(guān)鍵字,函數(shù)對屬性有寫權(quán)限。
結(jié)構(gòu)體中,計算屬性不具備存儲功能,所以不能給計算屬性賦值
只讀計算屬性,必須是var?
var length:Double{
return 22
}
如果結(jié)構(gòu)體內(nèi)部的函數(shù)對結(jié)構(gòu)體屬性進行修改,或者結(jié)構(gòu)體對象直接對結(jié)構(gòu)體屬性進行修改,那么創(chuàng)建結(jié)構(gòu)體對象的時候使用var
8.類可使用class static 修飾類方法,結(jié)構(gòu)體只能使用static, ?結(jié)構(gòu)體會自動創(chuàng)建包涵所有存儲屬性的構(gòu)造方法,類不會。
9 swift 中array dic string 結(jié)構(gòu)體 ?都是值類型,使用== != 進行比較 ? ?,class是引用類型,用=== !==進行比較。
10. 結(jié)構(gòu)體:若函數(shù)被static修飾,是結(jié)構(gòu)體的類型,否則結(jié)構(gòu)體對象,
class ,若在類方法中,是當前類的類型,否則類的對象。
枚舉體:即使類型,又是對象,看使用環(huán)境
11 .重寫set 和 get方法 ,如果值重寫了get方法,那么就是只讀屬性

12. 屬性監(jiān)聽

13 給btn添加事件,不能priva
14 // swift 自定義協(xié)議,必須遵守NSObjectProtocol
protocol MyDelegate :NSObjectProtocol {
func didLogin()
}
否則,會編譯失敗

同時一定要吧delegate設(shè)置weak ? ?
weak var delegate:MyDelegate?
swift 通過代理響應(yīng)方法不需要想oc一樣判斷有沒有代理對象,和該對象是否響應(yīng)協(xié)議方法,因為swift有可選鏈
delegate?.didLogin()
swift設(shè)置代理,該類必須要遵守這個代理,實現(xiàn)代理中必須要實現(xiàn)的方法
15.函數(shù)名和雷鳴沖突,會編譯失敗“use of undeclared type”
16.添加手勢響應(yīng)事件,按鈕的響應(yīng)事件,不能設(shè)置為private http://www.cocoachina.com/swift/20151023/13627.html
17. weak must be a mutable variable ,because it may change at runtime
18. 如果協(xié)議中使用到optional ,那么該協(xié)議必須加@objc修飾,
@objc protocol ToVCDelegate:NSObjectProtocol {
func must(num:Int)
@objc optional func choose(num:Int) ? //(swift 3 方法前?@objc )
}
19 變量在創(chuàng)建的時候,要嗎直接復(fù)制,要嗎設(shè)置為可控類型, 直接復(fù)制也不能直接置nil.(下面是錯誤的)
let str:String
str = nil
print(str?.isEmpty)
20 swift 類型安全,對于數(shù)組,字典這種包涵子元素的類型數(shù)據(jù),要嗎直接給定子元素類型,要嗎系統(tǒng)可以推斷出子元素類型
let arr = Array() //沒有給定Array子元素的類型,也沒有Array子元素,所以無法推斷出子元素類型,編譯失敗
// 編譯失?。篏eneric parameter 'Element' could not be inferred
所以正確的做法這樣
let arr:[String] = Array()
21;string(數(shù)組,字典。。也一樣) ?oc中使用的foundation 框架的NSString, NSStiring是一個類,引用類型,傳遞的是指針,swift中的String 是結(jié)構(gòu)體,傳遞給一個函數(shù)。方法。變量的時候,都是先復(fù)制,傳遞的是副本,二者地址是不一樣的,不是同一個東西, ?而Foundation框架的NSString ,傳遞的是指針,二者地址是一樣的,還是同一個東西
var str = "abc"
var str2 = str
print("\(unsafeAddressOf(str))? \n? \(unsafeAddressOf(str2))")
22:再懶加載的閉包里面訪問成員變量,必須要self. ? ?所有的閉包都是?
23.計算屬性,get set ? ,如果不重寫set ,那么該屬性就是只讀屬性,對于只讀的計算屬性,也只能用var聲明
24 結(jié)構(gòu)體和枚舉都是值類型,默認情況下,值類型的實例方法不能改變該實例的存儲屬性,使用mutating修改值類型的實例方法,使其變成可變方法,即可修改改實例的存儲屬性
struct Rectangle {
var width: Double
var height: Double
mutating func moveByX(x: Double, y: Double) {
width += x
height += y
}
}
?? 不可變實例(let)不能調(diào)用可變方法。
25.程序?qū)ο聵速x值時,swfit九轉(zhuǎn)為調(diào)用對應(yīng)的set部分代碼,至于該set部分是否真正的完成,swift并不關(guān)心;程序訪問下標,swfit轉(zhuǎn)為調(diào)用對應(yīng)的get部分代碼,至于該get部分代碼到底之行了什么,swift并不關(guān)心,只要該get部分最終返回一個類型匹配的值即可。
26:static : 在枚舉、結(jié)構(gòu)體、類中修飾屬性、方法,將它們變成類型屬性、類型方法
class: 在類中修飾屬性、方法,將它們變成類型屬性、類型方法。
使用static 修改的類型屬性、類型方法不能被子類重寫,使用class修飾的類型屬性和類型方法可以被子類重寫,
使用static修飾屬性屬性、方法,相當于同時使用class 和final。
27:方法類型定義變量
var myFunc: (() -> ())? ?// 最外層的()不能少
func hh() {
print("方法復(fù)制")
}
p.myFunc = hh
p.myFunc?()
28.閉包類型定義變量
var myClosure: ((Int) -> ())? // 最外層的()不能少
let closure = {(a: Int) -> Void in
print(a)
}
p.myClosure = closure
p.myClosure?(4)
29.在Swift中,要創(chuàng)建對象有以下幾種方式:
1、NSString.self()// 或者NSString.self.init()
2、let myClass = MyClass.Type.init()
3、let myClass = MyClass.self.init()
4、let type = NSClassFromString("MyClass") as! MyClass.Type然后通過type.init()來創(chuàng)建對象
30: 類方法
類方法中self 表示的xxx.type ?必須實現(xiàn)init方法之后,調(diào)用self.init() 即為創(chuàng)建對象
類方法沒有實際的存儲空間,不能被繼承/重寫
class func modelWithJson(json: [String : AnyObject]) -> AnyObject{
let obj = self.init()
obj.setValuesForKeysWithDictionary(json)
return obj
}
required override init() {
super.init()
}
31 不能擴展構(gòu)造方法
32 ?構(gòu)造器的坑和原則
如果重寫直接父類制定構(gòu)造器,還是使用override 修飾。比如Qubic_User: NSObject 那么Qubic_User在重寫init的時候需要使用override修飾。
比如:GatewayCell: UITableViewCell ?重寫init的時候不需要使用override修飾,因為init是UIVIew的,重寫init(style,reuse )的時候需要加上override。因為GatewayCell對象的直接父類是UITableViewCell
指定構(gòu)造器總是必須向上代理(調(diào)用父類的構(gòu)造器(如果有直接父類),不能調(diào)用便利構(gòu)造器)
便利構(gòu)造器總是必須橫向代理(調(diào)用當前類的其它構(gòu)造器,但是終點必須是指定構(gòu)造器)
一旦子類自定義了指定構(gòu)造器,那么就不會從父類繼承任何指定構(gòu)造器
33 private 的屬性在擴展里面不能訪問,
34.final修飾的方法不能被重寫,修飾的屬性和方法還是可以繼承的
35.擴展出來的屬性是可以被繼承和重寫的
36.擴展類屬性static?
extension Person {
@nonobjc static var info: String = "abc"
}
如果不加@noneObjc ,編譯失敗,a declaration cannot be both 'final' and 'dynamic'。
@noneObjc 作用
This issue arises because Swift is trying to generate a dynamic accessor for the static property for Obj-C compatibility, since the class inherits from NSObject.
If your project is in Swift only, rather than using a var accessor you can avoid the issue via the @nonobjc attribute in Swift 2.0:
37.Any :可代表任何類型,Int,Double等值類型 和 類的實例 var data:[String : Any] = [:]
AnyObject:可代表任何類的實例,? var data:[String : AnyObject] = [:] value: 不能放值類型數(shù)據(jù)
38擴展終結(jié)


39,閉包的循環(huán)解決方,weak self (弱引用) 和 [unowned me] (無主引用)
二者區(qū)別: 無主引用不允許接收nil(即必須始終有值),因此無主引用只能定義非可選類型
若閉包和捕捉的實例總是相互引用,且同時銷毀,宜采用無主引用,

若閉包捕獲的引用變量可能是nil的時候,將閉包捕獲的引變量定義為弱引用,弱引用必須是可選類型,當被引用的實例被銷毀后,弱引用的變量會自動被賦值為nil,利用這個特性,程序可以在閉包內(nèi)檢查捕獲的引用變量所引用的對象是否已經(jīng)被回收

40. 延遲工作
let delayTime = DispatchTime.now() + 10 ? ? ?
DispatchQueue.main.asyncAfter(deadline: delayTime) {? // choose now or global
// dowork
}
41.map flat降維原理
對于n維數(shù)組,flattop比map 多了一個result.append(contentsOf:) 將它們的數(shù)組中的內(nèi)容添加到結(jié)果集中,而不是數(shù)組本身 操作
42.通過setValuesForKeys(son) 給模型賦值的時候,必須保證json對應(yīng)key的value 和 模型對應(yīng)屬性類型相同,否則crash
Raytimer
/*屬性*/
var timers: [String: [RayTimerCMD]] = [:]
json
jsonTemp["timers"] = [] ? //[]crash ? ?[:]succeed
43.在擴展MBProgressHUD 的時候,欲設(shè)全局shareHUD,并且使用runtime綁定屬性view,
忽略細節(jié):對uiview進行了copy ??
OBJC_ASSOCIATION_COPY_NONATOMIC ??
OBJC_ASSOCIATION_COPY_NONATOMIC ?
(最后考慮,這種擴展思路不行,hud顯示的view得不到及時的釋放)
44 @objc 和dynamic ??swift是否有動態(tài)性
@objc
找到官方文檔讀讀。
可以知道@objc是用來將Swift的API導(dǎo)出給Objective-C和Objective-C runtime使用的,如果你的類繼承自O(shè)bjective-c的類(如NSObject)將會自動被編譯器插入@objc標識。
我們在把TestASwiftClass(純Swift類)的方法、屬性前都加個@objc 試試,如圖:
dynamic
文檔里還有一句說明:
加了@objc標識的方法、屬性無法保證都會被運行時調(diào)用,因為Swift會做靜態(tài)優(yōu)化。要想完全被動態(tài)調(diào)用,必須使用dynamic修飾。使用dynamic修飾將會隱式的加上@objc標識。
這也就解釋了為什么testReturnVoidWithaId無法被替換,因為寫在Swift里的代碼直接被編譯優(yōu)化成靜態(tài)調(diào)用了。
而viewDidAppear是繼承Objective-C類獲得的方法,本身就被修飾為dynamic,所以能被動態(tài)替換。
45.willSet 和 didSet 可以監(jiān)聽屬性的變化,比如給cell的model賦值,屬性類型包括(可選,!,默認值)

而不是重寫屬性的get set 方法(這是計算屬性特有標志)
46:swift 使用cocoa pods?
use_frameworks! # Add this if you are targeting iOS 8+ or using Swift
pod 'CocoaAsyncSocket'
47.swift3廢棄dispatch_once, 被替換成全局懶加載。
48.let distance = distance(toPoint: byPoint) 等號兩邊一樣,編譯錯誤: “variable used within its own initial value”
49

50: 閉包可以訪問和修改其所在上下文中的常量和變量(常量只能修改,不能訪問),這個過程被稱為捕獲,即使定義這些常量或變量的作用域已經(jīng)不存在了,閉包依然可以訪問或者修改他們, ?閉包是引用類型dede
如果閉包沒有沒強引用,執(zhí)行完之后,就沒了,也就丟棄了其所持有的對象