(Swift基礎)day01_(15)Swift中的閉包_2018-08-22

文丨lyh165
發(fā)布時間:2018-08-22 (周三 廣州/雨)
最后更新時間:2018-08-22 (周三 廣州/雨)

官方文檔
1、Welcome to Swift.org(歡迎來到Swift.org)
2、Using the Package Manager(使用包管理器)
3、A Swift Tour(快速之旅)
官方swift快速之旅code


閉包

閉包的介紹

  • 閉包和OC中的block非常相似
    • OC中的block是匿名的函數(shù)
    • Swift中的閉包是一個特殊的函數(shù)
    • block和閉包都經(jīng)常用于回調(diào)
  • 注意:閉包和block一樣,第一次使用時可能不習慣它的語法,可以先按照使用簡單的閉包,隨著學習的深入,慢慢掌握其靈活的運用方法.

閉包的使用

block的用法回顧
  • 定義網(wǎng)絡請求的類
@interface HttpTool : NSObject
- (void)loadRequest:(void (^)())callBackBlock;
@end

@implementation HttpTool
- (void)loadRequest:(void (^)())callBackBlock
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"加載網(wǎng)絡數(shù)據(jù):%@", [NSThread currentThread]);

        dispatch_async(dispatch_get_main_queue(), ^{
            callBackBlock();
        });
    });
}
@end

  • 進行網(wǎng)絡請求,請求到數(shù)據(jù)后利用block進行回調(diào)
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    [self.httpTool loadRequest:^{
        NSLog(@"主線程中,將數(shù)據(jù)回調(diào).%@", [NSThread currentThread]);
    }];
}

  • block寫法總結:
block的寫法:
    類型:
    返回值(^block的名稱)(block的參數(shù))

    值:
    ^(參數(shù)列表) {
        // 執(zhí)行的代碼
    };

使用閉包代替block
  • 定義網(wǎng)絡請求的類
class HttpTool: NSObject {

    func loadRequest(callBack : ()->()){
        dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
            print("加載數(shù)據(jù)", [NSThread.currentThread()])

             dispatch_async(dispatch_get_main_queue(), { () -> Void in
                callBack()
             })
        }
    }
}

  • 進行網(wǎng)絡請求,請求到數(shù)據(jù)后利用閉包進行回調(diào)
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        // 網(wǎng)絡請求
        httpTool.loadRequest ({ () -> () in
            print("回到主線程", NSThread.currentThread());
        })
    }

  • 閉包寫法總結:
閉包的寫法:
    類型:(形參列表)->(返回值)
    技巧:初學者定義閉包類型,直接寫()->().再填充參數(shù)和返回值

    值:
    {
        (形參) -> 返回值類型 in
        // 執(zhí)行代碼
    }

閉包的簡寫
  • 如果閉包沒有參數(shù),沒有返回值.in和in之前的內(nèi)容可以省略
    httpTool.loadRequest({
        print("回到主線程", NSThread.currentThread());
    })

  • 尾隨閉包寫法:
    • 如果閉包是函數(shù)的最后一個參數(shù),則可以將閉包寫在()后面
    • 如果函數(shù)只有一個參數(shù),并且這個參數(shù)是閉包,那么()可以不寫
    httpTool.loadRequest() {
        print("回到主線程", NSThread.currentThread());
    }

    // 開發(fā)中建議該寫法
    httpTool.loadRequest {
        print("回到主線程", NSThread.currentThread());
    }

閉包的循環(huán)引用

  • 如果在HttpTool中有對閉包進行強引用,則會形成循環(huán)引用
  • 補充:在Swift中檢測一個對象是否銷毀,可以實現(xiàn)對象的deinit函數(shù)
    // 析構函數(shù)(相當于OC中dealloc方法)
    deinit {
        print("ViewController----deinit")
    }

  • 循環(huán)引用的(實現(xiàn))
    • 該實現(xiàn)是為了產(chǎn)生循環(huán)引用,而產(chǎn)生的循環(huán)引用
class HttpTool: NSObject {

    // 定義屬性,來強引用傳入的閉包
    var callBack : (()->())?

    func loadRequest(callBack : ()->()){
        dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
            print("加載數(shù)據(jù)", [NSThread.currentThread()])

             dispatch_async(dispatch_get_main_queue(), { () -> Void in
                callBack()
             })
        }

        self.callBack = callBack
    }
}

  • swift中解決循環(huán)引用的方式
  • 方案一:
    • 使用weak,對當前控制器使用弱引用
    • 但是因為self可能有值也可能沒有值,因此weakSelf是一個可選類型,在真正使用時可以對其強制解包(該處強制解包沒有問題,因為控制器一定存在,否則無法調(diào)用所在函數(shù))
    // 解決方案一:
    weak var weakSelf = self
    httpTool.loadData {
        print("加載數(shù)據(jù)完成,更新界面:", NSThread.currentThread())
        weakSelf!.view.backgroundColor = UIColor.redColor()
    }

  • 方案二:
    • 和方案一類型,只是書寫方式更加簡單
    • 可以寫在閉包中,并且在閉包中用到的self都是弱引用
    httpTool.loadData {[weak self] () -> () in
        print("加載數(shù)據(jù)完成,更新界面:", NSThread.currentThread())
        self!.view.backgroundColor = UIColor.redColor()
    }

  • 方案三:(常用)
    • 使用關鍵字unowned
    • 從行為上來說 unowned 更像OC中的 unsafe_unretained
    • unowned 表示:即使它原來引用的對象被釋放了,仍然會保持對被已經(jīng)釋放了的對象的一個 "無效的" 引用,它不能是 Optional 值,也不會被指向 nil
httpTool.loadData {[unowned self] () -> () in
        print("加載數(shù)據(jù)完成,更新界面:", NSThread.currentThread())
        self.view.backgroundColor = UIColor.redColor()
    }

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 1、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明AI閱讀 16,172評論 3 119
  • 在上一篇文章Swift中的變量和常量中我總結了一些自己對于變量和常量的認識,最近學習了閉包,順便給大家分享一下關于...
    老板娘來盤一血閱讀 18,875評論 16 87
  • 技 術 文 章 / 超 人 對于IOS來說,由于系統(tǒng)是封閉的,APP上架需要通過App Store,安全性來說相當...
    樹下敲代碼的超人閱讀 10,885評論 47 77
  • 如果當一個人只剩下絕望可以用來滿足自己,他會變得十分積極?!嗬っ桌?白銀案兇犯落網(wǎng)。大出警方意外,本以為十惡...
    萌之刺刺閱讀 990評論 8 12
  • 那段旅程33天,我沒有想過它會是什么樣子,只知道我想出去轉(zhuǎn)轉(zhuǎn)、看看… 起初我不知道怎么去跟父母說,...
    情懷家閱讀 121評論 0 0

友情鏈接更多精彩內(nèi)容