iOS Block用法及原理

//Block语法

//^返回值类型(参数列表){表达式}

- (void)some{

    ^int(int count){

        return count + 1;

    };

    //返回值类型可省略

    ^(int count){

        return count + 1;

    };

    //参数列表为空,可省略

    ^{

        return @"123";

    };

    //最简洁的语法:^{};


}

- (block)someActionTwo:(block)block{

    return^(inti){

        block(2);

        returni +1;

    };

}

blockblockt =  [selfsomeActionTwo:^int(inti) {

        NSLog(@"##########i");

        returni;

    }];

block的用法

1.block作为参数

[selfsomeAction:^int(inti) {

        NSLog(@"i");

        returni ++;

    }];

- (void)someAction:(int(^)(inti))block{

    block(2);

}

2.block作为属性变量

//Block类型变量 语法:返回值类型(^变量名)(参数列表)

@property(nonatomic,copy)NSString *(^Block)(NSString *strone);

//借助typedef可简写typedef int(^block)(int);

block的分类

block分为栈block:_NSConcreteStackBlock,堆block:_NSConcreteMallocBlock,全局block:_NSConcreteGlobalBlock

栈block:block最初是在栈上创建的,只用到局部变量,没有被强指针指向的block是栈block;

堆block:在ARC中,系统会视情况而定(一旦block被赋值就会被copy到堆上),将栈上的block,copy到堆上,这是因为栈上的内存是有系统控制的,栈block出了作用域就会被销毁,为了延长block的生命周期,将其copy到堆上

全局block:生命周期从创建开始到程序结束,相当于单例的存在,它不会用到临时变量,只会用到全局或静态变量或者没有用到变量

block对外界变量的捕获

block可以捕获任何外界变量,捕获到之后会将其作为自身结构体的成员变量,其中局部变量,静态变量会被追加到block结构体的构造函数中,从clang翻译的源码中可以看到:

void (*Block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, &static_k, val));

block的构造函数追加了局部变量的值,和静态变量的地址

 static int j = 10;

    inti =10;

  void(^block)(void) =  ^{

        NSLog(@"打印i:%dj:%d",i,j);

    };

    i++;

    j++;

    block();

打印结果为i:10,而不是11,因为block只捕获了局部变量的值,没有捕获地址,block内部会用到什么,在它创建的时候就会去捕获什么,这时候捕获到的也只能是值,为了防止局部变量之后被销毁,需要知道它的值的时候取不到了,所以是提前捕获,后续改变量的值在怎么变化,block取的都是最初捕获的值.  j:11,因为j是静态变量捕获了它的地址,所以可以实时获取j的值。

block内部修改外部变量


如果block内部直接修改外部变量,编译器会提示我们要加上__block ,为什么需要加上__block就可以修改了呢?

1.block捕获外界局部变量只是捕获了它的值,并没有捕获它的地址,对它只有只读能力,没有写的能力

2.被__block修饰之后,该变量会被转换为一个结构体:

struct __Block_byref_i_0 {

  void *__isa;

__Block_byref_i_0 *__forwarding;

int __flags;

int __size;

int i;

};

结构体中,它里面包含了isa,forwarding指针,flag标示,size大小,变量值,名字和变量名同名,在block的构造函数中 我们可以看到,追加了forwarding指针,block可以通过forwarding指针访问变量,进而操作变量。

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