zoukankan      html  css  js  c++  java
  • Block语法(1)

      1. 为什么要使用block。

    我们知道,对象与对象之间的通信方式有以下三种:1、代理-协议;2、通知;3、block。三种方式都实现了对象之间的解耦合。其中不同就是:通知的通信方式是1对多;代理、block的通信方式是1对1.

      2.Block的简介。

    • Block是iOS4.0之后新增的一种语法结构,也成为“闭包”。
    • SDK4.0新增的API大量使用了block
    • Block是一个匿名的函数代码块,此代码块可以作为参数传递给其他对象。

      3. Block的使用

    //int 是返回值;sumBlock 是Block变量类型;(int x,int y)括号里面是参数。
    int(^sumBlock)(int x,int y);

     

     1 //创建 myBlock
     2 - (void)createMyBlock {
     3     //定义block变量
     4     int(^sumBlock)(int x,int y);
     5     //实现block,并且赋值
     6     sumBlock = ^(int x,int y){
     7         return x + y;
     8     };
     9     //声明myBlock变量,全局{int(^myBlock)(int x,int y);}
    10     myBlock = sumBlock;
    11     NSLog(@"%d",myBlock(20,20));
    12 }

      4. 创建Block

    Block有以下4种方式:

     1 //Block是匿名函数,无法通过函数名调用,所以单独使用没有意义
     2 //  1.无参数  无返回值--与直接打印数据是一样的效果,无意义
     3     ^(){
     4         NSLog(@"无参数  无返回值");
     5     }();
     6     
     7 //  2.有参数 无返回值
     8     ^(int a,NSString* text){
     9         NSLog(@"%d 
     %@",a,text);
    10     }(10,@"有参数  无返回值");
    11     
    12 //  3.有返回值  无参数
    13     NSString* a = ^(){
    14         return @"无参数  有返回值";
    15     }();
    16     NSLog(@"%@",a);
    17     
    18 //  4.有参数  有返回值
    19     //定义block变量
    20     int(^sumBlock)(int x,int y);
    21     //实现block,并且赋值
    22     sumBlock = ^(int x,int y){
    23         return x + y;
    24     };
    25     NSLog(@"%d",sumBlock(10,10));
    26 }
    1 //有参数 有返回值(返回结果是 6 )
    2     int(^powefBlock)(int x,int y);
    3     powefBlock = ^(int x,int y){        
    4         return x * y;
    5     };
    6     NSLog(@" powef = %d",powefBlock(2,3));

      5. Block和变量

    • 变量按作用可以分为全局变量和局部变量。
    • block中可以使用这两种变量,但是有不同的管理机制。

    引用局部变量

    • block引用局部变量时候,改变量会作为常量编码到block块中。
    • 局部变量需要使用__block修饰,才能在block中修改。
     1 //      如果在block 代码内部,使用外部变量时,number会变为常量
     2     int  number = 10;
     3     ^(){
     4     //number = 20; 直接报错 ---不可以修改,已经变为常量
     5         NSLog(@"%d",number);
     6     }();
     7 
     8 //--在内部改变-
     9   //在变量前加__block 声明即可
    10     __block int  number_1 = 10;
    11     ^(){
    12         number_1 = 20;
    13         NSLog(@"%d",number_1);
    14     }();
    • 引用外部变量
    #import <Foundation/Foundation.h>
    
    @interface MyObject : NSObject
    {    
        //block 引用外部 成员变量
        int _number;
    }
    - (void)log;
    
    @end
     1 - (void)log {
     2    
     3 //      block 引用外部 成员变量
     4     _number = 99;
     5     NSLog(@"---%ld-- ",self.retainCount);    
     6 //  使用block 修饰obj 对象  这样obj 在block中使用不会被retain。
     7 //  obj 不能拥有 self 的所有权   block不会持有self对象
     8     __block MyObject* obj = self;    
     9     ^(){
    10         //    判断 obj 是否存在
    11         if (!obj) {
    12             return ;
    13         }
    14         //通过obj 获取成员变量;打印结果是 1 
    15         int a = obj -> _number;
    16         NSLog(@"---%d-- ",a);
    17         NSLog(@"*****%ld**** ",self.retainCount);
    18     }();
    19     
    20 }

       6. Block的内存管理

    • 在block里面引用一个局部的Objective-C对象的时候,该对象会被retain。
    • 如果局部变量使用__block修饰,则不会被retain。 
     1 //--------引用外部obj对象的时候----------
     2 //不会被retain,即obj1.retainCount始终是1
     3 //__block NSObject* obj1 = [[NSObject alloc] init];
     4 //延时调用以后,obj1.retainCount会变为2
     5     NSObject* obj1 = [[NSObject alloc] init];
     6     NSLog(@"%ld",obj1.retainCount);
     7     
     8     //延时调用
     9     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{        
    10         NSLog(@"%ld",obj1.retainCount);
    11     });
    • block本身可以像对象一样copy和release
    • block创建后内存是分配在栈上,调用copy方法之后,将block移动到堆中。
    • 当block声明为全局变量时候,应该调用block的copy方法。

      7. 循环引用

    • 在block(点语法)里面引用一个实例变量的时候,改实例变量会被retain。
    • 如上规则容易导致循环引用,造成内

    欢迎读者查阅,如若转载,请标明出处。

  • 相关阅读:
    20169220 2016-2017-2 <网络攻防实践> 课程总结
    20169220 <网络攻防实践> 第十四周实验—免杀
    20169220 <网络攻防实践> 第十二周实验—SQL注入
    20169220 <网络攻防实践> 第十一周实验—SQL注入+TCP/IP攻击
    20169220 <网络攻防实践> 第十周实验—Nmap+Wireshark+缓冲区溢出漏洞
    20169220 <网络攻防实践> 第九周实验——Nmap
    20169220 <网络攻防实践> 第八周实验——网络攻防虚拟机环境搭建
    20169220 <网络攻防实践> 第七周学习总结
    20169220 <网络攻防实践> 第六周学习总结
    20169220 <网络攻防实践> 第五周学习总结
  • 原文地址:https://www.cnblogs.com/david-han/p/4862222.html
Copyright © 2011-2022 走看看