闭包
1.闭包在swift中有点像C和C++的函数指针,跟OC中的block一致
闭包的定义
//定义
//无参数无返回值的闭包
var completionCallback :(()->())?
//无参数有返回值的闭包
var completionHandler:(()->Int)?
//有参数无返回值的闭包
var finishCallBack :((Int) ->())?
//有参数有返回值的闭包
var successHandler :((Int) ->(Int))?
//无参数无返回值的闭包
completionCallback = { Voidin
print("无参数无返回值的闭包执行了");
};
completionCallback!();
//闭包赋值
//无参数有返回值的闭包
completionHandler = { Intin
print("闭包被调用了");
return20;
};
let a =completionHandler!();
print(" a:\(a)")
//有参数无返回值的闭包
finishCallBack = { (a)in
print("有参数无返回值的闭包 a:\(a)")
};
finishCallBack!(10);
//有参数有返回值的闭包
successHandler = {(a) ->(Int)in
print("有参数有返回值 a:\(a)");
return10;
};
let result =successHandler!(20);
print(result);
// 闭包作为参数传递的情况
func successFunction(success:@escaping (Int)->(Int)) -> () {
successHandler = success;
let result = success(10);
print("successFunction result :::\(result)")
}
func doSomthing(finish:@escaping (Int)->()) -> () {
finishCallBack = finish;
finish(10);
}
func loadNetWorkData(completion:@escaping ()->Int) -> () {
completionHandler = completion;
let a = completion();
print("a:\(a)");
}
func loadDatas(completion:@escaping ()->()) -> () {
completionCallback = completion;
DispatchQueue.global().async {
print("耗时操作\(Thread.current)");
//主线程更新UI
DispatchQueue.main.async(execute: {
print("\(Thread.current)");
completion();
})
}
}
//闭包使用外部变量
//定义一个闭包 左边参数名右边参数值记得加问号不然会报未初始化的错误
var completionCallback :(()->())?
//closure可以修改外部变量名了!!!!
var a =10;
completionCallback = { Void in
print("使用外部参数===>\(a)");
//使用外部参数===>10
//如果是修改呢
a = 20;
print("修改后a的值\(a)");
//修改后a的值 20
};
completionCallback!();
======>经过尝试在swift 3.0中可以改变外部变量的值了 这与OC中的不一样 OC如果需要修改外部参数需要加上__Block修饰
// 在swift中 经过侧是 在调用之前参数的值在外部可以修改了 我觉得应该是传递的是地址 所以可以修改了
// 在OC中 这样会输出 10
var a =10;
completionCallback = { Voidin
print("使用外部参数===>\(a)");//使用外部参数===>10
};
a = 20;
completionCallback!();
//闭包中的循环引用
// 测试方法 通过 出栈检测
overridefunc viewDidLoad() {
super.viewDidLoad()
// 利用类似git的图标下面查看图层的东西可以检查是否有循环引用
loadDatas {
print(self.view);
}
}
func loadDatas(completion:@escaping ()->()) -> () {
completionCallback = completion;
DispatchQueue.global().async {
print("耗时操作\(Thread.current)");
//主线程更新UI
DispatchQueue.main.async(execute: {
print("\(Thread.current)");
completion();
})
}
}
//析构函数
deinit {
print("我挂了");
}
// 以上方法
NextViewController在出栈的时候并不会调用析构函数
//方法一 使用OC方法
weak var weakSelf =self;
loadDatas {
print(weakSelf?.view);
}
//方法二 苹果推荐方法
loadDatas { [weak self]in
print(self?.view);
}
以上两种方法都可以解决循环引用
// 另外Xcode8上 有点像git分支的那个图标可以帮我们使用图形化界面分析是否构成循环引用 具体步骤请看附件
本片纯是个人总结 改天我会总结一篇关于block的博客