objective c 代码块blocks完整总结二

1. block基础 block声明有点像c语言的函数指针

C代码

  1. int func(int);
  2. int (*pfunc)(int);
  3. int func(int p)
  4. {
  5. printf("%d", p);
  6. return p;
  7. }

其中func是函数, pfunc是函数指针
函数指针赋值  pfunc = &func;
函数指针使用 (*pfunc)(100);
block的声明 int (^bfunc)(int);
block的赋值 bfunc = ^(int p){   printf("%d", p);   return p; };
block的使用 bfunc(10);
有些情况下,用户需要在多个地方用到签名相同的block,那么可以用typedef来定义block类型, 如

C代码

  1. typedef int (^MyBlock)(int);
  2. MyBlock block1 = ^(int p){
  3. printf("%d", p);
  4. return p;
  5. }
  6. MyBlock block2 = ^(int p){
  7. printf("%d", p * 2);
  8. return p * 2;
  9. }

2. block对外部变量的使用 对于全局变量,静态变量,类成员变量处理方式是相同的,但对于局部变量,在定义完block之后,它的值就被固定了,即使在block本身被调用之前修改了,在block内部使用的局部变量依然是block被定义时的值
以下是示例代码,其中var1是全局变量, var2是全局静态变量, var3是类的成员变量, var4是函数的局部变量。

C代码

  1. typedef void (^MyBlock)(int);
  2. ….
  3. var1 = 1;
  4. MyBlock block1 = ^(int p)
  5. {
  6. printf("\nvar1:%d", var1);
  7. };
  8. block1(0);
  9. var1 = 2;
  10. block1(0);
  11. var2 = 2;
  12. MyBlock block2 = ^(int p)
  13. {
  14. printf("\nvar2:%d", var2);
  15. };
  16. block2(0);
  17. var2 = 3;
  18. block2(0);
  19. var3 = 3;
  20. MyBlock block3 = ^(int p)
  21. {
  22. printf("\nvar3:%d", var3);
  23. };
  24. block3(0);
  25. var3 = 4;
  26. block3(0);
  27. var4 = 4;
  28. MyBlock block4 = ^(int p)
  29. {
  30. printf("\nvar4:%d", var4);
  31. };
  32. block4(0);
  33. var4 = 5;
  34. block4(0);

这段代码执行的结果是: var1:1 var1:2 var2:2 var2:3 var3:3 var3:4 var4:4 var4:4
对于全局变量、静态变量和类成员变量,block中的代码是可以修改它们的值的。 但对于局部变量,默认情况下block把它当作常量处理,如果需要修改,必须在局部变量定义的地方加上修饰符 __block
3. block和Objective-C对象变量
对于全局变量和静态变量,相比普通变量没有任何特殊的地方。 根据apple的官方文档,对于成员变量和局部变量,在block中引用会引起retainCount的变化。对成员变量的直接引用会使成员变量所在的那个对象retainCount + 1, 对局部变量的引用会使局部变量的retainCount + 1。如果对局部变量使用__block作为修饰符,就可以使局部变量被block引用时不进行retain的操作。
我自己尝试了一下,发现有一点apple的文档里没有写清楚,block对成员变量和局部变量引用时并不一定会引起retainCount的变化,以下是我的测试代码。
obj3是成员变量

C代码

  1. obj3 = [[TestObjectalloc] init];
  2. printf("\nself retain count:%d", [selfretainCount]);
  3. MyBlock block6 = ^(int p)
  4. {
  5. printf("\nself retain count:%d", [selfretainCount]);
  6. printf("\nobj retain count:%d", [obj3retainCount]);
  7. };
  8. block6(0);
  9. printf("\nself retain count:%d", [selfretainCount]);

输出结果: self retain count:1 self retain count:1 obj retain count:1 self retain count:1

C代码

  1. obj3 = [[TestObjectalloc] init];
  2. printf("\nself retain count:%d", [selfretainCount]);
  3. MyBlock block7 = ^(int p)
  4. {
  5. printf("\nself retain count:%d", [selfretainCount]);
  6. printf("\nobj retain count:%d", [obj3retainCount]);
  7. };
  8. MyBlock block77 = Block_copy(block7);
  9. block7(0); //或者 block77(0);
  10. printf("\nself retain count:%d", [selfretainCount]);
  11. Block_release(block77);
  12. printf("\nself retain count:%d", [selfretainCount]);

self retain count:1 self retain count:2 obj retain count:1 self retain count:2 self retain count:1
obj4是局部变量

C代码

  1. TestObject *obj4 = [[TestObjectalloc] initWithValue:4];
  2. MyBlock block8 = ^(int p)
  3. {
  4. printf("\nobj4 retain count:%d", [obj4 retainCount]);
  5. };
  6. MyBlock block88 = Block_copy(block8);
  7. block88(0);
  8. printf("\nobj4 retain count:%d", [obj4 retainCount]);
  9. Block_release(block88);
  10. printf("\nobj4 retain count:%d", [obj4 retainCount]);

obj4 retain count:2 obj4 retain count:2 obj4 retain count:1

C代码

  1. __block TestObject *obj5 = [[TestObjectalloc] initWithValue:5];
  2. MyBlock block9 = ^(int p)
  3. {
  4. printf("\nobj5 retain count:%d", [obj5 retainCount]);
  5. };
  6. MyBlock block99 = Block_copy(block9);
  7. block99(0);
  8. printf("\nobj5 retain count:%d", [obj5 retainCount]);
  9. Block_release(block99);
  10. printf("\nobj5 retain count:%d", [obj5 retainCount]);

obj5 retain count:1 obj5 retain count:1 obj5 retain count:1
结论是在一个方法内的block对对象的引用不会引起retainCount变化,但是调用Block_copy以后,retainCount会变化,但是block执行完以后引用对象的retainCount不会增加,需要调用Block_release才能释放之前Block_copy引起的retainCount增加。

时间: 2024-10-14 08:03:59

objective c 代码块blocks完整总结二的相关文章

objective c 代码块blocks完整总结一

在ios4之后,引入了代码块的特性,在gcd中会经常的用到,所以决定好好的看看代码块文档,把这块总结一下.从头开始讲解代码块. 1.声明和使用代码块 一般用^操作符声明一个块变量,并作为块的开始符.而块的本身用{}包括起来,就像下面那样. int multiplier = 7; int (^myBlock)(int) = ^(int num) { return num * multiplier; }; int(^myblocks)(int)=(^int  num){return num * mu

Python 代码块 小数据池

一  代码块 什么是代码块??? Python程序是由代码块构造的.先举一个例子: 1 for i in '12334567': 2 print(i) 1 def func(): 2 print('Hello,world!') 1 class A: 2 name = 'colin' 从上面的例子可以称为代码块,虽然上面的缩进的内容都叫代码块,但是他们并不是python中严格定义的代码块. 那么,python中真正意义上的代码块又怎么定义? 因此,我们定义:一个模块,一个函数,一个类,一个文件等都

初学Objective - C语法之代码块(block)

一.block声明 1.无参数,无返回值: void (^sayHi)(); 2.有参数,有返回值: NSInteger (^operateOfValue)(NSInteger num); block的声明:返回值类型(^block变量名)(参数列表) 脱字符(^)是块的语法标记 二.block实现 block变量名 = ^返回值类型(参数列表) 1.  sayHi = ^{ NSLog(@"你好"); }; 2. operateOfValue = ^ NSInteger (NSInt

代码块(block)之函数体(二)

代码块存储的数据是一个函数体.使用代码块是,你可以像调用其他标准函数一样,传入参数数,并得到返回值. //block作为函数的参数 //函数返回值类型 函数名(block的声明格式) void fun(int (^block)(int a,int b)){ int sum=block(5,6); NSLog(@"%d",sum); } void fun1(NSString *(^myBlock)(NSString *s),NSString *s1){ NSLog(@"%@&q

二、Java面向对象(10)_代码块

2018-05-02 代码块 什么是代码块? 在类或者方法中,使用"{}"将多行代码封装在一起,形成一个独立的代码区,这就构成了代码块. 在代码块里的变量属于局部变量,只在自己所在区域的前后{}内有效. 代码块的分类 根据代码块定义的位置不同,分成三种 1.局部代码块:在方法里用一对"{}"括起来的数据,就是局部代码块, 一般我们不会直接使用局部代码块,只不过我们会结合if,while,for,try等关键字联合,表示一块代码区域. 2.初始化代码块(构造代码块):

Objective-C 14 代码块Block

Blocks Block 代码段 Block封装了一段代码,可以在任何时候执行.它是对C语言中函数的扩展,它实际上是C语言实现的,所以它在各种以C作为基础的语言哪都是有效的,包括Objective-C.C++以及Objective-C++. Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值.它和传统的函数指针很类似,但是有区别: block是内联函数的,并且默认情况下它对局部变量是只读的. 苹果官方建议尽量多用block.在多线程.异步任务.集合遍历.集合排序.动画转

Objective-c 05 类别 类扩展 委托 非正式协议 协议 代码块 并发性 队列

类别 为已经存在的类添加行为时,通常采用创建子类的方法,不过有时子类并不方便, 比如:创建NSString的子类,但是NSString实际上只是一个类簇的表面形式.因而为这样的类创建子类会非常困难.在其他情况下, 也许可以创建它的子类,但是用到的工具集和库无法帮你处理新类的对象的.例如:当使用stringWithFormat:类方法生成新字符串时,你创建的 NSString类的新子类就无法返回.   利用Objective-C的动态运行时分配机制,可以为现有的类添加新的方法.这些新的方法在Obj

一篇文章看懂iOS代码块Block

iOS代码块Block 概述 代码块Block是苹果在iOS4开始引入的对C语言的扩展,用来实现匿名函数的特性,Block是一种特殊的数据类型,其可以正常定义变量.作为参数.作为返回值,特殊地,Block还可以保存一段代码,在需要的时候调用,目前Block已经广泛应用于iOS开发中,常用于GCD.动画.排序及各类回调 注: Block的声明与赋值只是保存了一段代码段,必须调用才能执行内部代码 Block变量的声明.赋值与调用 Block变量的声明 Block变量的声明格式为: 返回值类型(^Bl

Python小数据池,代码块解析

一.id,is,== 在Python中,id是什么?id是内存地址,比如你利用id()内置函数查询一个数据的内存地址: name = '太白' print(id(name)) # 1585831283968 那么is又是什么?==又是什么? == 是比较两边的数值是否相等,而is是比较两边的内存地址是否相等.如果内存地址相等,那么这两边其实是指向同一个内存地址. 可以说如果内存地址相同,那么值肯定相同,但是如果值相同,内存地址不一定相同. 二.代码块 根据官网提示我们可以获知: 根据提示我们从官