Block 由浅入深

作者: BEYOND黄 | 来源:发表于2017-05-26 23:42 被阅读25次

    Block是对象。

    如何判断mrc,arc

    1.delloc 能否调用super,能mrc,不能arc。

    2.retain release能用mrc

    ARC管理原则:只要一个对象没有被强指针修饰就会被销毁,默认局部变量都是强指针,存放到栈区里面

    MRC小常识:1.没有使用strong,weak,局部变量对象就是相当于基本数据类型

                           2.MRC给属性赋值,一定要用set方法,不能直接访问下划线成员属性赋值。

    在Block使用中,Block内部能够读取外部局部变量的值。但我们需要改变这个变量的值时,我们需要给它附加上__block修饰符。没有用_block修饰的话,默认复制局部变量到block里,此时是更改局部变量值,并不能改变block内部的局部变量的值。而用_block修饰的话,会将局部变量的地址复制过去,所以更改局部变量,block会读取到这个变化。

    MRC:管理block:只要block中引用了外部局部变量,block就放在栈里面。如果block没有引用外部局部变量,block放在全局区。block只能使用copy,不能使用retain。因为使用retain,block还是在栈里。用copy放在堆里。

    ARC:管理block:只要block中引用了外部局部变量,block就放在堆里面。因为局部变量在arc是强指针。如果block没有引用外部局部变量,block放在全局区。block声明用strong修饰,最好不用copy修饰。copy的set方法会进行判断。 block声明用weak修饰,会被销毁。

    一。block 访问外面变量规则:

    》block 内部可以访问外面的变量。

    》默认情况下,block 内部不能修改外面的局部变量;但可以修改全局变量。

    》给局部变量加上 __block 关键字,那么这个局部变量就可以在block 内部修改。

    二。利用 typedef 定义block 类型:防止多次定义

    》typedef int (^MyBlock)(int , int ) ;

    // 以后就可以利用MyBlock这种类型来定义block变量。

    MyBlock b1  ;

    b1 = ^(int a , int b ){

    return a - b ;

    }  ;

    MyBlock b2 = ^(int a , int  b) {

    return a + b ;

    } ;

    Block几大关键点:

    1.保存代码块

    void(^block)()=^{

    NSLog(@"调用block");

    };

    Block变量的声明格式为: 

    返回值类型(^Block名字)(参数列表);

    // 声明一个无返回值,参数为两个字符串对象,叫做

    aBlock的Blockvoid(^aBlock)(NSString*x,NSString*y);

    // 形参变量名称可以省略,只留有变量类型即可

    void(^aBlock)(NSString*,NSString*);

    注: ^被称作"脱字符"

    Block变量的赋值

    Block变量的赋值格式为:

     Block变量 = ^(参数列表){函数体};

    aBlock = ^(NSString*x,NSString*y){

    NSLog(@"%@ ---- %@", x, y);};

    2.传值

    相比于代理,block传值很简洁

    Block声明:

    @interfaceMViewController :UIViewController

    @property(nonatomic,strong)void(^block1)(NSString*value);

    @end

    Block赋值

    MViewController*vc = [[MViewControlleralloc]init];

    vc.view.backgroundColor= [UIColorblueColor];

    vc.block1= ^(NSString*value) {

    NSLog(@"%@",value);

    };

    [self presentViewController:vcanimated:YEScompletion:nil];

    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event{

    if(_block1) {

    _block1(@"123");

    }

    打印结果

    3.block循环引用:

    我引用你,你引用我。造成双方都不会销毁,造成内存泄漏。

    __weak typeof(self) weakSelf =self;

    如果在block要使用延时执行,加上

    __weak typeof(weakSelf) strongSelf =weakSelf;

    执行完block时在销毁。

    4.block变量传递

    inta =3;

    void(^block)()=^{

    NSLog(@"%d",a);

    };

    a=5;

    block();

    输出是3,因为值已经传进去了。

    static int a =3;

    void(^block)()=^{

    NSLog(@"%d",a);

    };

    a=5;

    block();

    输出是5.

    总结:如果是局部变量,block是值传递。如果是全局变量或者静态变量,_block修饰的变量,是指针传递。

    5.block当参数使用:

    把block当参数使用,并不是马上调用,而是方法决定。做什么事由外部决定,什么时候做由内部决定

    #import

    @interfaceCalculator :NSObject

    @property(nonatomic,assign)NSIntegerresult;

    - (void)calculator:(NSInteger(^)(NSInteger))calblock;

    @end

    #import"Calculator.h"

    @implementationCalculator

    - (void)calculator:(NSInteger(^)(NSInteger))calblock{

    if(calblock) {

    _result= calblock(_result);

    }

    }

    Calculator*cal = [[Calculatoralloc]init];

    [calcalculator:^(NSIntegerresult){

    result +=10;

    returnresult;

    }];

    NSLog(@"%ld",(long)cal.result);

    6.block当返回值使用


    相关文章

      网友评论

        本文标题:Block 由浅入深

        本文链接:https://www.haomeiwen.com/subject/cbctfxtx.html