Block 由浅入深

Block是对象。

如何判断mrc,arc

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

2.retain release能用mrc

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

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

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


Block 由浅入深_第1张图片

在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 由浅入深)