!?編程
?表示可選類型,若是申明屬性或變量的話就是默認值爲nil的意思,swift
!表示解包,對加!的在使用 前必定要作判nil處理,通常用if let 和 guard let來判斷,或者用 if a != nil 來作判斷api
閉包的使用閉包
閉包的表達式:async
{(參數)-> 返回值 in函數
//代碼spa
}代理
使用例子code
申明爲變量:對象
typealias Swiftblock = (String,Any) -> Void
var testBlock: Swiftblock?
複製代碼
使用:
testBlock?("ddd","ffffff")
複製代碼
實現:
{ [weak self] (a,b) in
print(a)
print(b)
}
[weak self]是爲了防止循環引用,(a,b)是傳過來的參數
複製代碼
逃逸閉包:
就是閉包做爲函數的參數,可是在函數結束之後纔去執行這個參數的就叫逃逸閉包,在參數類型前加@escaping
逃逸閉包的使用例子
private func requestData(success:@escaping (Any) -> Void) {
DispatchQueue.global().async {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3, execute: {
success("data") //3秒後才執行閉包success
})
}
複製代碼
在這個例子中閉包success做爲參數,可是他在函數執行完之後過了一段時間才執行,因此他就是逃逸閉包
例子:
requestData { (data) in
let str: String = data as! String //由於data是Any類型的付值給String類型的就須要作類型匹配 ,用as!要確保類型一致且不爲nil
print(str)
//或者用as? 來作類型匹配以下
if let stra = data as? String {
print(stra)
}
let strb: String = data as? String ?? ""
print(strb)
guard let strc = data as? String else {
return
}
print(strc)
}
func requestData(success:@escaping (Any) -> Void) {
success("data")
}
複製代碼
上面例子中由於參數data是Any類型的付值給String類型的時候就須要作類型匹配
申明函數參數或返回值的時候加?,不然傳參數或返回返回值的時候對於可選類型的值要加!
寫代理模式的時候
protocol CCDelegate : class {
func doSomething()
}
複製代碼
記得在後面加上class關鍵字,通常加class ,
代理看成變量的時候用weak 修飾防止循環引用
weak var delegate: CCDelegate?
複製代碼
if let 和 guard let 的用法,通常用來作非空判斷
var some: String?
if some != nil{
print(some!)
}
//或者
guard some != nil else{ return }
print(some!)
//上面的判斷用 if let 和guard let 以下
if let aSome = some{
print(aSome)
}
guard let aSome = some else {
return
}
print(aSome)
複製代碼
7.swift單例的使用
單例的通常書寫格式
class SingleTest {
static let shared = SingleTest()
private init() {} //必定要加private防止外部經過init直接建立實例
}
複製代碼
單例的使用例子:
單例類
class SingleTest {
var aValue: NSString?
var bValue: NSString?
static let shared = SingleTest()
private init() {} //必定要加private防止外部經過init直接建立實例
}
單例的使用
SingleTest.shared.aValue = "aaa"
SingleTest.shared.bValue = "bbb"
print("SingleTest.shared.aValue =\(SingleTest.shared.aValue ?? "kong")")
//輸出結果爲:SingleTest.shared.aValue =aaa
複製代碼
.type 是類的類型至關於oc中的Class,
.self 是 靜態的在編譯時就肯定的類 至關於oc中的class
type(of:) 是實例的類 ,至關於oc 中的 class
例子:
let aa = "aaaa"
let stringMetaType: String.Type = String.self
let stringInstanceType: String.Type = type(of: aa)
print("stringMetaType = \(stringMetaType)")
print("stringInstanceType = \(stringInstanceType)")
if type(of: aa) == String.self {
print("bbbbbbbb")
}
if type(of: aa) is String.Type{
print("cccccc")
}
複製代碼
//打印結果以下
stringMetaType = String
stringInstanceType = String
bbbbbbbb
cccccc
從上面的例子能夠獲得驗證
協議的通常書寫格式
protocol TestProtocol {
var testVar: Int { get set}
func testFunc()
}
複製代碼
Protocol是約定的一種協議,協議中能夠有變量,和方法,協議就是一種約定,若是某個對象遵照了該約定就要去實現該約定(協議)的方法和變量(若是遵照了就比如是承諾了就得去實現),協議中方法和變量也能夠定義爲可選(optional)類型的,若是變量或方法是可選類型的就不須要必定去實現。
協議中方法和變量爲可選的protocol格式以下:
@objc protocol TestProtocol {
@objc optional var testVar: Int { get set} //可選
//協議中的變量須要指定 get set
@objc optional func testFunc() //可選
func noOptionFunc() //不可選
}
複製代碼
協議的使用
class TestClas: TestProtocol {
//實現協議TestProtocol中的方法
func noOptionFunc() {
print("必定要實現的函數")
}
//實現協議TestProtocol中的方法
func testFunc() {
print("不須要必定實現的函數")
}
}
複製代碼
protocol中的 associatedtype關鍵字
associatedtype用來定義一個在協議中的「泛型」類型 定義爲 associatedtype類型的在實現協議的類中使用的時候指明該類型的具體類型是什麼就能夠了
associatedtype的例子以下
protocol TestProtocol {
associatedtype Num
func testFunc() -> Num
}
class TestClassInt: TestProtocol {
func testFunc() -> Int {
return 1
}
}
class TestClassDouble: TestProtocol {
func testFunc() -> Double {
return 1.666666666
}
}
複製代碼
上面例子 TestProtocol中的 Num 被定義爲associatedtype,在 TestClassInt和TestClassDouble中用的時候 把Num分別替換爲相應的Int 和 Double便可
協議的擴展( Protocol Extension):
協議擴展能夠給協議內部的函數添加實現以及給協議添加新的函數等,從而將函數功能添加到遵照協議的全部類型中
例子以下:
@objc protocol Person {
@objc optional var age: Int { get set}
@objc optional func work()
}
extension Person {
func work(){
print("我想上廁所")
}
func run() {
print("我在跑步")
}
}
class Man:Person {
var age: Int = 20
func run() {
print("我是男的也在跑步")
}
}
class Woman: Person {
var age: Int = 18
func work() {
print("去女廁所上廁所")
}
}
let man = Man()
man.work()
man.run()
let woman = Woman()
woman.work()
woman.run()
複製代碼
//打印結果以下
//我想上廁所
//我是男的也在跑步
//去女廁所上廁所
//我在跑步
複製代碼
上面例子就是對協議擴展的應用
面向協議編程(POP)的理解
簡單理解面向協議編程就是用定義協議來代替面向對象編程中的繼承多繼承等還能達到使用靈活和解偶的目的。
@objc protocol Person {
@objc optional var age: Int { get set}
@objc optional func work()
}
複製代碼
//男性
class Man:Person {
var age: Int = 20
func work() {
print("去男廁所上廁所")
}
}
複製代碼
//女性
class Woman: Person {
var age: Int = 18
func work() {
print("去女廁所上廁所")
}
}
複製代碼
上面例子中定義了一個Person的協議,讓Man類和Woman類遵照Person協議就能夠達到面向對象編程中繼承的效果,若是有多個協議要遵照的話就能夠經過遵照多個協議來達到面向對象編程中的多繼承的效果
一些基礎的總結,有不對的地方還請留言指正