• objective c 代码块blocks完整总结二


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

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

    其中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.   
    7. MyBlock block2 = ^(int p){  
    8.   printf("%d", p * 2);  
    9.   return p * 2;  
    10. }  

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

    C代码 
    1. typedef void (^MyBlock)(int);  
    2. ….  
    3.   
    4.   
    5. var1 = 1;  
    6. MyBlock block1 = ^(int p)  
    7. {  
    8.     printf(" var1:%d", var1);  
    9. };  
    10.   
    11. block1(0);  
    12. var1 = 2;  
    13. block1(0);  
    14.      
    15. var2 = 2;  
    16. MyBlock block2 = ^(int p)  
    17. {  
    18.     printf(" var2:%d", var2);  
    19. };  
    20.   
    21.   
    22. block2(0);  
    23. var2 = 3;  
    24. block2(0);  
    25.      
    26. var3 = 3;  
    27. MyBlock block3 = ^(int p)  
    28. {  
    29.     printf(" var3:%d", var3);  
    30. };  
    31.      
    32. block3(0);  
    33. var3 = 4;  
    34. block3(0);  
    35.      
    36. var4 = 4;  
    37. MyBlock block4 = ^(int p)  
    38. {  
    39.     printf(" var4:%d", var4);  
    40. };  
    41.   
    42.   
    43. block4(0);  
    44. var4 = 5;  
    45. 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(" self retain count:%d", [selfretainCount]);  
    3. MyBlock block6 = ^(int p)  
    4. {  
    5.     printf(" self retain count:%d", [selfretainCount]);  
    6.     printf(" obj retain count:%d", [obj3retainCount]);  
    7. };  
    8. block6(0);  
    9. printf(" self 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(" self retain count:%d", [selfretainCount]);  
    3. MyBlock block7 = ^(int p)  
    4. {  
    5.     printf(" self retain count:%d", [selfretainCount]);  
    6.     printf(" obj retain count:%d", [obj3retainCount]);  
    7. };  
    8. MyBlock block77 = Block_copy(block7);  
    9. block7(0); //或者 block77(0);  
    10. printf(" self retain count:%d", [selfretainCount]);  
    11. Block_release(block77);  
    12. printf(" self 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(" obj4 retain count:%d", [obj4 retainCount]);  
    5. };  
    6. MyBlock block88 = Block_copy(block8);  
    7. block88(0);  
    8. printf(" obj4 retain count:%d", [obj4 retainCount]);  
    9. Block_release(block88);  
    10. printf(" obj4 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(" obj5 retain count:%d", [obj5 retainCount]);  
    5. };  
    6. MyBlock block99 = Block_copy(block9);  
    7. block99(0);  
    8. printf(" obj5 retain count:%d", [obj5 retainCount]);  
    9. Block_release(block99);  
    10. printf(" obj5 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增加。

  • 相关阅读:
    循环的注意点
    c语言实践输出某个区间中不是3的倍数的偶数
    while循环for循环优缺点和应用
    while 和do while循环的区别
    多重if else和switch case的区别
    if else的执行流程
    多个if和一个ifelse的区别
    对两个变量排序,从小到大输出
    【译】第四篇 Integration Services:增量加载-Updating Rows
    【译】第三篇 Integration Services:增量加载-Adding Rows
  • 原文地址:https://www.cnblogs.com/transcendent/p/4149163.html
Copyright © 2020-2023  润新知