swift基礎(chǔ)-閉包

一,Block的回顧

1,Block通常會(huì)用在網(wǎng)絡(luò)請(qǐng)求中,請(qǐng)求到數(shù)據(jù)后然后回調(diào),先自定義HttpTool的工具類
實(shí)現(xiàn)下請(qǐng)求數(shù)據(jù)的方法

@implementation HttpTool

-(void)loadData:(void(^)(NSString * json))callBack;
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
   
        NSLog(@"%@",[NSThread currentThread]);
    
        dispatch_async(dispatch_get_main_queue(), ^{
        
            NSLog(@"%@",[NSThread currentThread]);
            callBack(@"222");
        });
    });
}
@end

2,然后在控制器里創(chuàng)建對(duì)象調(diào)用請(qǐng)求方法,等到請(qǐng)求數(shù)據(jù)后就能再Block里做其他的處理了

@interface ViewController ()

@property(nonatomic,strong) HttpTool * tool;

@end

@implementation ViewController

- (void)viewDidLoad {
     [super viewDidLoad];
    self.tool = [HttpTool new];

}
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
        [self.tool loadData:^(NSString *json) {
        NSLog(@"%@",json);
  }];
}
@end
二,用閉包來(lái)重寫上面的邏輯
1,閉包的類型:(參數(shù)列表) -> (返回值列表)
import UIKit

class HttpTool: NSObject {

func loadData(callBack : (json : String)->()) {
  
    dispatch_async(dispatch_get_global_queue(0, 0)) {
        
        print("\(NSThread.currentThread())")
        
        dispatch_sync(dispatch_get_main_queue(), {
            print("\(NSThread.currentThread())")
            callBack(json: "json")
            
        })
    }
    
  }
}

2,在控制器調(diào)用

import UIKit

class ViewController: UIViewController {

var tool : HttpTool = HttpTool()

override func viewDidLoad() {
    super.viewDidLoad()
    
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    tool.loadData { (json) in
        print("\(json)")
    }

 }   
}
三,閉包的循環(huán)引用
40CFA1B3-5340-4795-88BF-14526C407707.png
1,第一個(gè)例子中由于HttpTool并沒(méi)有對(duì)callBack這個(gè)Block產(chǎn)生強(qiáng)引用,所以不會(huì)循環(huán)引用,所以在HttpTool中屬性描述一個(gè)Block,然后強(qiáng)引用callBack,就會(huì)發(fā)生循環(huán)引用了

#import "HttpTool.h"

@interface HttpTool ()

@property(nonatomic,copy) void(^callBack)(NSString * json);

@end

@implementation HttpTool

-(void)loadData:(void(^)(NSString * json))callBack;
{
    //強(qiáng)引用
    self.callBack = callBack;
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
   
        NSLog(@"%@",[NSThread currentThread]);
    
        dispatch_async(dispatch_get_main_queue(), ^{
        
            NSLog(@"%@",[NSThread currentThread]);
            callBack(@"222");
        });
    
    });
}
@end
如果不對(duì)循環(huán)引用做處理的話,執(zhí)行結(jié)果是:
18E55EAC-1D2A-4DF2-B159-33CB89DBA6A6.png
只要我們weak self 就可以解決循環(huán)引用了
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    __weak ViewController * weakSelf = self;
    [self.tool loadData:^(NSString *json) {
        NSLog(@"%@",json);
        weakSelf.view.backgroundColor = [UIColor redColor];
    }];
}
EFFF6E8F-57D3-47CC-B337-63B17860751F.png
2,同樣要解決閉包的循環(huán)引用讓HttpTool強(qiáng)引用這個(gè)閉包c(diǎn)allBack
import UIKit
class HttpTool: NSObject {
    //聲明成可選類型的閉包
    var callBack :((json : String)->())?
    func loadData(callBack : (json : String)->()) {
    //強(qiáng)引用
    self.callBack = callBack
    dispatch_async(dispatch_get_global_queue(0, 0)) {
        
        print("\(NSThread.currentThread())")
        
        dispatch_sync(dispatch_get_main_queue(), {
            print("\(NSThread.currentThread())")
            callBack(json: "json")
            
        })
        }
    }
}

3,swift中解決閉包循環(huán)引用的3種方式

import UIKit

class ViewController: UIViewController {

    var tool : HttpTool = HttpTool()

    override func viewDidLoad() {
        super.viewDidLoad()
    
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        /*
           weak var weakSelf = self
           tool.loadData { (json) in
            print("\(json)")
          //weakSelf?.view : 如果前面的可選類型,沒(méi)有值,后面的所有代碼不會(huì)執(zhí)行
          //如果有值,系統(tǒng)會(huì)自動(dòng)將weakSelf進(jìn)行解包,并使用weakSelf
          weakSelf?.view.backgroundColor = UIColor.redColor()
       }
       */
    
    
    tool.loadData {[weak self] (json) in
        print("\(json)")
        //weakSelf?.view : 如果前面的可選類型,沒(méi)有值,后面的所有代碼不會(huì)執(zhí)行
        //如果有值,系統(tǒng)會(huì)自動(dòng)將weakSelf進(jìn)行解包,并使用weakSelf
        self?.view.backgroundColor = UIColor.redColor()
    }
    
  
    /*
    //這種寫法一旦self為空,就會(huì)報(bào)錯(cuò)
    //unowned相當(dāng)于oc中的__unsafe_unretained,__unsafe_unretained 修飾的弱引用,如果指向的對(duì)象銷毀,那么指針指向之前的內(nèi)存地址,很容易產(chǎn)生壞內(nèi)存訪問(wèn),野指針。僵尸對(duì)象
    tool.loadData {[unowned self] (json) in
        print("\(json)")
        //weakSelf?.view : 如果前面的可選類型,沒(méi)有值,后面的所有代碼不會(huì)執(zhí)行
        //如果有值,系統(tǒng)會(huì)自動(dòng)將weakSelf進(jìn)行解包,并使用weakSelf
        self.view.backgroundColor = UIColor.redColor()
    }
    */

    
}
    //相當(dāng)于oc中的dealloc方法
    deinit{
        print("deinit")
    
    }

}
四,尾隨閉包
    //普通寫法
    tool.loadData ({[weak self] (json) in
        print("\(json)")
        //weakSelf?.view : 如果前面的可選類型,沒(méi)有值,后面的所有代碼不會(huì)執(zhí)行
        //如果有值,系統(tǒng)會(huì)自動(dòng)將weakSelf進(jìn)行解包,并使用weakSelf
        self?.view.backgroundColor = UIColor.redColor()
    })
    //尾隨閉包一
    tool.loadData (){[weak self] (json) in
        print("\(json)")
        //weakSelf?.view : 如果前面的可選類型,沒(méi)有值,后面的所有代碼不會(huì)執(zhí)行
        //如果有值,系統(tǒng)會(huì)自動(dòng)將weakSelf進(jìn)行解包,并使用weakSelf
        self?.view.backgroundColor = UIColor.redColor()
    }
   //尾隨閉包二,當(dāng)閉包為函數(shù)的最后一個(gè)參數(shù)時(shí),會(huì)自動(dòng)省略()
    tool.loadData {[weak self] (json) in
        print("\(json)")
        //weakSelf?.view : 如果前面的可選類型,沒(méi)有值,后面的所有代碼不會(huì)執(zhí)行
        //如果有值,系統(tǒng)會(huì)自動(dòng)將weakSelf進(jìn)行解包,并使用weakSelf
        self?.view.backgroundColor = UIColor.redColor()
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 閉包可以捕獲和存儲(chǔ)其所在上下文中任意常量和變量的引用。這就是所謂的閉合并包裹著這些常量和變量,俗稱閉包 閉包和OC...
    翻這個(gè)墻閱讀 424評(píng)論 0 0
  • 閉包是自包含的函數(shù)代碼塊,可以在代碼中被傳遞和使用。Swift 中的閉包與 C 和 Objective-C 中的代...
    莽原奔馬668閱讀 1,964評(píng)論 2 12
  • 閉包和OC中的Block差不多,也是保存一段代碼,在適當(dāng)?shù)臅r(shí)候執(zhí)行,一般用于一些耗時(shí)操作,也可以傳遞值 區(qū)別:bl...
    埃林的奶酪閱讀 853評(píng)論 0 0
  • 閉包表達(dá)式語(yǔ)法 閉包表達(dá)式語(yǔ)法有如下的一般形式: 1 { (parameters) -> (return type...
    T9的第三個(gè)三角閱讀 300評(píng)論 0 1
  • iOS網(wǎng)絡(luò)架構(gòu)討論梳理整理中。。。 其實(shí)如果沒(méi)有APIManager這一層是沒(méi)法使用delegate的,畢竟多個(gè)單...
    yhtang閱讀 5,494評(píng)論 1 23

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