Block基础

一个最基本的block

void (^block)(void) = ^(void){
    NSLog(@"这是一个无参数无返回值的block");
};
block();//block的灵活性
这边有个思考,如上的block是在储存的哪个区域?

如果没有深究,凭经验可以说它存在常量区或栈区,因为当前block只是临时变量。
实际上block存在堆区,因为在当前的ARC环境下,block一旦定义出来,编译器就会自动把栈上的block copy到堆里面。
这边再思考一下,block是用什么修饰呢?你可能说copy,那strong是否可以呢?其实strong也是可以的,在当前的arc下,其实已经没有什么区别。

block的分类

首先了解一下几个存储区域:
  • 代码段:写的代码都存在这边
  • 数据区(常量区):存放全局变量,NSGlobalBlock存放在这边
  • 栈区:存放局部变量,不需要程序员管理,系统自动分配,自动销毁,NSStackBlock存放在这
  • 堆区:存放我们自己alloc出来的对象,动态分配内存,需要程序员自己申请内存,自己管理,NSMallocBlock存放在这
// -| NSGlobalBlock
// 没有引用auto变量
void (^block)(void) = ^(void){
    NSLog(@"没有引用auto变量");
}
NSLog(@"%@",block); //这边用%@ --> block是一个对象
// -| NSStackBlock 
// 这边需要MRC环境
// 访问了auto变量
int a = 10; // -->栈区
void (^block)(void) = ^(void){
    NSLog(@"访问了auto变量 %d",a);
}
NSLog(@"%@",block);
// -| NSMallocBlock 
// ARC环境Xcode帮我们处理成了堆block 
// 防止出现释放了还去访问导致野指针crash
int a = 10; // -->栈区
void (^block)(void) = ^(void){
    NSLog(@"ARC环境 访问了auto变量 %d",a);
}
NSLog(@"%@",block);
总结:
Block类型 环境 内存 拷贝
NSGlobalBlock 没有访问auto变量 数据区 什么也不做
NSStackBlock 访问auto变量 从栈复制到堆
NSMallocBlock NSStackBlock调用了copy 引用计数增加

在ARC环境下,编译器会自动将栈上的block copy到堆上

block的使用——链式编程

block当作函数的返回值
- (void)viewDidLoad 
{
    self.getSomeString(@"后被处理");
}
- (void(^)(NSString *))getSomeString
{
    void(^block)(NSString *) = ^(NSString *sting){
        NSLog(@"这边进行一系列处理 %@",sting);
    };
    NSLog(@"这边会被先调用");
    return block;
}
block当作函数的参数

异步性:比如AFN的successBlock和failBlock

- (void)viewDidLoad 
{
    [self request:^(NSString *string) {
        NSLog(@"%@",string);
    }];
}
- (void)request:(void(^)(NSString* string))block
{
    block(@"异步处理一些问题");
}
block当作一个参数

灵活性:保存一段代码块,在任何想用的地方去调用实现

block的变量截获
1、局部变量截获,是值的截获
int num = 10;
void(^block)(void) = ^(void){
    NSLog(@"num = %d",num);
};
num = 20;
block();

这里num的打印值为10,原因就是对局部变量的截获是值截获。

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1",@"2",nil];
void(^block)(void) = ^(void){
    NSLog(@"%@",arr);
    [arr addObject:@"4"];
};
[arr addObject:@"3"];
arr = nil;
block();

这里的打印为1,2,3,局部对象变量的截获也是一样,是截获的值,而不是指针,在外部将其置nil也对block没有影响,但是对象调用方法会影响

2、局部静态变量截获,是指针截获
static int num = 10;
void(^block)(void) = ^(void){
    NSLog(@"num = %d",num);
};
num = 20;
block();

这里num的打印值为20,意味着num = 20修改有效的,即是指针截获,同样,在block里去修改变量num也是有效的。

3、全局变量,静态全局变量block是不截获的,直接进行访问

具体的可以通过通过命令clang -rewrite-objc xxx.m生成.cpp文件,或者通过xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-9.0.0 XX.m.m文件转成 .cpp文件,查看c++的代码。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • block本质上是封装了函数调用以及函数调用环境的OC对象,为什么这么说呢?我们可以从底层数据结构来看.下面是创建...
    夜沐月阅读 437评论 0 0
  • Block基础和retain cycle(循环引用) blcok简介 Block 是c语言的扩展,并不是什么高新技...
    董军1990阅读 12,294评论 22 69
  • 目录一,本质二,变量捕获三,类型四,对象类型的auto变量 一,本质 1,实例代码 2,底层代码(用clang进行...
    码小菜阅读 242评论 0 3
  • block块是在ios4开始,就出现了。block实质就是C语言的回调函数。block函数定义如下 void (^...
    zl520k阅读 183评论 0 0
  • 在iOS 4.0之后,block横空出世,它本身封装了一段代码并将这段代码当做变量,通过block()的方式进行回...
    Clark_new阅读 480评论 0 4