Block 由浅入深

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



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • iOS代码块Block 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,B...
    smile刺客阅读 2,495评论 2 26
  • 前言 Blocks是C语言的扩充功能,而Apple 在OS X Snow Leopard 和 iOS 4中引入了这...
    小人不才阅读 3,903评论 0 23
  • Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等。用过GCD就知道Block的精妙之处。...
    Coder_JMicheal阅读 854评论 2 1
  • 曾经面试过一个iOS开发,让他写一个参数是int返回值是void的Block声明,这位同学思考了一会儿只能很尴尬的...
    LordLamb阅读 629评论 1 4
  • 转自李峰峰博客 一、概述 闭包 = 一个函数「或指向函数的指针」+ 该函数执行的外部的上下文变量「也就是自由变量」...
    Joshua520阅读 1,144评论 0 0

友情链接更多精彩内容