• Swift入门 三


    Block

    • Block格式:
    • 形参:

    返回值类型(^Block名称)(形参列表)

    • 值:

    ^(形参列表){

    // 逻辑代码

    }

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {  
        [self loadData:^{
            NSLog(@"%@", [NSThread currentThread]);
            NSLog(@"回到主线程更新UI");
        }];
    
    }
    - (void)loadData:(void(^)())myBlock
    {
        // 1.异步获取数据
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"%@", [NSThread currentThread]);
            NSLog(@"异步获取数据");
            // 2.回到主线程更新UI
            dispatch_async(dispatch_get_main_queue(), ^{
                
                myBlock();
            });
            
        });
    }

    闭包

    • 闭包和OC中的Block很像
    • OC中的Block类似于匿名函数
    • Swift中的闭包就是一个特殊的函数
    • Block一般用于回调,异步准备数据,然后通过Block回调更新UI

    闭包的格式:

    • (形参列表) -> 返回值

    技巧:

    • 闭包类型,先写上 () -> () 然后再根据具体情况进行定义

    值:

    • in的作用就是用于分隔逻辑代码和描述
    {
    
    (形参列表) -> 返回值类型
    
    in
    
      //逻辑代码
    
    }
    

    闭包的简写

    • 如果没有返回值也没有参数,那么in和in之前的代码可以删除
    • 如果闭包是形参列表的最后一个参数,那么可以把闭包写到()的后面
    • 如果函数只有一个形参,并且这个形参是一个闭包,那么()可以不写
    • loadData({ () -> () in ***code****})
    • loadData( { ***code*** } )
    • loadData (){ ***code*** } //称为尾随闭包
    • loadData { ***code*** } // 称为尾随闭包  推荐这种写法
    //        loadData ({ () -> () in
    //            print(NSThread.currentThread())
    //            print("回到主线程更新UI")
    //        })
            
    //        loadData ({
    //            print(NSThread.currentThread())
    //            print("回到主线程更新UI")
    //        })
            
            // 以下两种写法, 我们称之为尾随闭包
    //        loadData (){
    //            print(NSThread.currentThread())
    //            print("回到主线程更新UI")
    //        }
            
            // 开发中建议写下面这一种写法
            loadData {
                print(NSThread.currentThread())
                print("回到主线程更新UI")
            }
        }
    
    
        func loadData(myBlock: ()->())
        {
            dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
                print(NSThread.currentThread())
                print("异步准备数据")
                
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    myBlock()
                })
            }
        }
    

     闭包的循环引用

    • OC中Block的循环引用: __weak typeof(self) weakSelf = self ;
    • Swift中闭包的循环引用的解决方法: weak var weakSelf = self  //因为变量是weak的,随时有可能被释放,所以系统推导是可选类型
    class ViewController: UIViewController { 
    
        // 报错的原因: Swift规定一个对象中的属性必须在对象初始化时全部初始化
    
        // 如果没有在初始化时给所有的属性赋值, 那么就会报错
    
        // 要想不报错, 那么可以让属性变成可选的
    
        
    
        // 注意: 错误写法()->()? , 这中写法代表闭包的返回值是可选的, 而不是闭包是可选的
    
        // 可选类型的值, 如果没有初始化, 那么默认值就是nil
    
        var finished: (()->())?
    
        
    
        override func viewDidLoad() {
    
            super.viewDidLoad()
    
            // Do any additional setup after loading the view, typically from a nib.
    
            view.backgroundColor = UIColor.purpleColor()
    
        }
    
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {      
    
    /*
    
      // 方法1
    
           //  OC中: __weak typeof(self) weakSelf = self;
    
           // 因为变量是weak的, 随时有可能被释放, 所以系统推导是可选类型
    
            // Swift中: weak var weakSelf = self 
    
           weak var weakSelf = self
    
       loadData { () -> () in
    
                print(NSThread.currentThread())
    
                print("回到主线程更新UI")
    
                weakSelf!.view.backgroundColor = UIColor.redColor()    //weakSelf 强制解包
    
            }
    
    */
    
    /*
    
      //方法2
    
       loadData { [weak self]() -> () in   //[weak self]
    
                print(NSThread.currentThread())
    
                print("回到主线程更新UI")
    
                self!.view.backgroundColor = UIColor.redColor()    //self 强制解包
    
            }
    
    */
    
            // 方法3   开发中推荐这样写
    
           //  Swift中的weak对应OC中的__weak, 如果对象释放了, 那么会自动将变量赋值为nil
    
            // Swift中的unowned对应OC中的__unsafe_unretained,  如果对象释放了, 不会将变量赋值为nil, 如果对象释放了再继续访问会出现野指针错误
    
     
    
            loadData { [unowned self] () -> () in   //[unownes self]
    
                print(NSThread.currentThread())
    
                print("回到主线程更新UI")
    
                self.view.backgroundColor = UIColor.redColor()   
    
            }
    
        }
    
        
    
        func loadData(myBlock: ()->())
    
        {
    
            dispatch_async(dispatch_get_global_queue(0, 0)) { () -> Void in
    
                print(NSThread.currentThread())
    
                print("异步准备数据")
    
                
    
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
    
                    self.finished = myBlock
    
                    myBlock()
    
                })
    
            }
    
        } 
    
        // OC : dealloc
    
        // Swift: deinit
    
        deinit
    
        {
    
            // 只要对象释放就会调用这个方法
    
            print("滚")
    
        }
    
     
    
    }
    
  • 相关阅读:
    python汉诺塔
    圆周率计算
    PIL: 建立一个GIF图
    Jieba库使用和好玩的词云
    Turtle库的建立——汉诺塔
    计算pi的精度+进度条显示
    Python——我所学习的turtle函数库
    Python——教你画朵太阳花
    Python常用模块re的使用
    正则表达式字符组/元字符/量词
  • 原文地址:https://www.cnblogs.com/aunty/p/4940472.html
Copyright © 2020-2023  润新知