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当返回值使用