1.oc中的block
ViewController.m
#import "ViewController.h"
#import "HttpTools.h"
@interface ViewController ()
@property (nonatomic, strong) HttpTools *tools;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tools = [[HttpTools alloc] init];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
// 閉包&控制器&HttpTools對象有沒有形成循環引用
__weak ViewController *weakSelf = self;
[self.tools loadData:^(NSString *jsonData) {
// NSLog(@"在控制器中,拿到數據:%@", jsonData);
weakSelf.view.backgroundColor = [UIColor redColor];
}];
}
- (void)dealloc {
NSLog(@"ViewController -- dealloc");
}
@end
HttpTools.h
#import <Foundation/Foundation.h>
@interface HttpTools : NSObject
- (void)loadData:(void(^)(NSString *))finishedCallback;
@end
HttpTools.m
#import "HttpTools.h"
@interface HttpTools()
@property(nonatomic ,copy) void (^finishedCallback)(NSString *);
@end
@implementation HttpTools
- (void)loadData:(void (^)(NSString *))finishedCallback
{
self.finishedCallback = finishedCallback;
// 1.發送網絡的異步請求
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"已經發送了網絡請求:%@", [NSThread currentThread]);
// 2.回到主線程
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"回到主線程:%@", [NSThread currentThread]);
// 3.獲取數據, 并且將數據回調出去
finishedCallback(@"json數據");
});
});
}
@end
2.swift中的閉包
HttpTools.swift
import UIKit
class HttpTools {
var finishedCallback : ((_ jsonData : String) -> ())?
// 閉包類型: (_ 參數列表) -> (返回值類型)
// @escaping : 逃逸的
func loadData(_ finishedCallback : @escaping (_ jsonData : String) -> ()) {
self.finishedCallback = finishedCallback
// 1.發送異步網絡請求
DispatchQueue.global().async {
print("發送異步網絡請求:\(Thread.current)")
DispatchQueue.main.sync {
print("回到主線程:\(Thread.current)")
finishedCallback("json數據")
}
}
}
}
ViewController.swift
import UIKit
class ViewController: UIViewController {
var httpTools : HttpTools?
// 在swift中只要是對父類的方法進行重寫, 必須在方法前加上override
override func viewDidLoad() {
super.viewDidLoad()
httpTools = HttpTools()
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// 解決循環引用的方案:
// 解決方案一:
/*
weak var weakSelf : ViewController? = self
httpTools?.loadData({ (jsonData : String) in
weakSelf?.view.backgroundColor = UIColor.red
})
*/
// 解決方案二:
/*
httpTools?.loadData({[weak self] (jsonData : String) in
self?.view.backgroundColor = UIColor.red
})
*/
// 解決方案三:
// unowned --> unsafe_unretained(野指針)
httpTools?.loadData({[unowned self] (jsonData : String) in
self.view.backgroundColor = UIColor.red
})
// 尾隨閉包的概念(不建議)
// 如果在函數中, 閉包是最后一個參數, 那么可以寫成尾隨閉包
httpTools?.loadData() {[unowned self] (jsonData : String) in
self.view.backgroundColor = UIColor.red
}
// 如果是唯一的參數, 也可以將前面的()省略掉
httpTools?.loadData {[unowned self] (jsonData : String) in
self.view.backgroundColor = UIColor.red
}
}
deinit {
print("ViewController -- deinit")
}
}