Swift闭包

//1、首先看一下函数结构
func test(name:String) -> String {
   return ("输出了\(name)")
}

//2、OC中的Block与Swift中的---带参数---闭包比较

//OC
void (^test) (NSString *)=^(NSString *name){
     NSLog(@"%@",name);
};
test(@"测试");

//swift
let test={(_ name:String)->() in // in 后面就是回调之后处理的函数 ,相当于是Block之后的{ }
    print(name) 
}
test("测试")

//3、在函数中当做---参数进行传递---

//OC
-(void)loadData:(  void(^)(void) )completetion
{
   completetion();
}
比如:
-(void)loadData:(  void(^)(NSArray *) )completetion
{
//这里暂时先忽略掉线程,简单处理,重点在swift闭包
    NSLog(@"耗时操作");
    sleep(2);//模拟网络请求
    NSArray *arr=@[@"1",@"2"];
    NSLog(@"主线程回调");
    completetion(arr); //返回获得的数据
}


 [self loadData:^(NSArray *callBack){
      NSLog(@"%@,%@",callBack[0],callBack[1]);
  }];


//Swift
func loadData(completetion: (返回值)->()) -> () {
   completetion()
}
比如:
 func loadDate(completion: @escaping (_ result : [String])->()) -> () {
//这里有一个很重要的参数 @escaping,逃逸闭包
//简单来说就是 闭包在这个函数结束前内被调用,就是非逃逸闭包,调用的地方超过了这函数的范围,叫逃逸闭包
//一般网络请求都是请求后一段时间这个闭包才执行,所以都是逃逸闭包。
// 在Swift3.0中所有的闭包都默认为非逃逸闭包,所以需要用@escaping来修饰
        DispatchQueue.global().async {
            print("耗时操作\(Thread.current)")
            Thread.sleep(forTimeInterval: 2)
            let json=["1","2"]
            DispatchQueue.main.async {
                print("主线程更新\(Thread.current)")
                completion(json)
//函数在执行完后俩秒,主线程才回调数据,超过了函数的范围,这里就是属于逃逸闭包,如果不用@escaping,编译器是编译不过的
            }
        }
    }


 loadDate { (callBack) in
        print("\(callBack)")
 }

3、作为属性进行传递

//OC
简单,再次忽略,如有不懂,请Google

//Swift
    其中作为属性进行传递时,可分为几种:
    1> var blockProperty : (Int,Int) -> String = { _ , _ in return ""} // 带初始化方式  
    2> var blockPropertyNoReturn : (String) -> () = { _ in }  
    在使用时,不需要再判断其是否存在(if let .... {}),因为已经初始化
    class BlockTest: NSObject {

        var blockIvar : (String,String) -> String = {_ , _  in return ""}

        func testBlcok() {
            let result = blockIvar("wojiao","wjy")
            print("我是Block作为属性进行传值的结果----\(result)")
        }
    }
    
    3> typealias  blockFunc = (String , String)  -> (String)
    import UIKit
    typealias  blockFunc = (String , String)  -> (String)
    class BlockTest: NSObject {
        //var blockIvar: blockFunc?
        //func testBlcok() {
            //if blockIvar != nil {
                //let result = blockIvar!("wojiao","wjy")
                //print("我是Block作为属性进行船只的结果----\(result)")
            //}
        //}
        var blockIvar: blockFunc!
        func testBlcok() {
            if blockIvar != nil {
                let result = blockIvar("wojiao","wjy")
                print("我是Block作为属性进行船只的结果----\(result)")
            }
        }
    }

//测试闭包(block)
    func blockTest()  {
        let blockTest = BlockTest()
        blockTest.blockIvar = {(first:String , second:String) -> String in
            return first+second
        }
        blockTest.testBlcok()
    }



4、循环引用
//第一种
weak var weakwelf=self
//套用oc的方式(__weak typedef(weakself)=self).
//这里要注意,不能用  let  ,因为self可能会释放指向nil,相当于是一个可变值

//调可选项发送消息的时候 用 ? 解包 不用 !
pringt("weakself ?.view") 不用" weakself!.view"
//因为强制解包一旦weakself=nil时会崩溃

//第二种
//[weak self]标识在{}中所有的self都是弱引用
 loadDate { [weak self] in
            print(self?.view)
 }

5、尾随闭包
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。可以使用尾随闭包来增强函数的可读性。
func someFunctionThatTakesAClosure(closure: () -> ()) {
    // 函数体部分
}

// 以下是不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure({
    // 闭包主体部分
})

// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
    // 闭包主体部分
}

猜你喜欢

转载自blog.csdn.net/wjy0629/article/details/81252195
今日推荐