`
qwjcool
  • 浏览: 68937 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

Objective-C Blocks研究

阅读更多

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

int func(int);

int (*pfunc)(int);

int func(int p)
{
  printf("%d", p);
  return p;
}

 


其中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类型, 如

typedef int (^MyBlock)(int);
MyBlock block1 = ^(int p){
  printf("%d", p);
  return p;
}

MyBlock block2 = ^(int p){
  printf("%d", p * 2);
  return p * 2;
}

 


2. block对外部变量的使用
对于全局变量,静态变量,类成员变量处理方式是相同的,但对于局部变量,在定义完block之后,它的值就被固定了,即使在block本身被调用之前修改了,在block内部使用的局部变量依然是block被定义时的值

以下是示例代码,其中var1是全局变量, var2是全局静态变量, var3是类的成员变量, var4是函数的局部变量。

typedef void (^MyBlock)(int);
….


var1 = 1;
MyBlock block1 = ^(int p)
{
    printf("\nvar1:%d", var1);
};

block1(0);
var1 = 2;
block1(0);
   
var2 = 2;
MyBlock block2 = ^(int p)
{
    printf("\nvar2:%d", var2);
};


block2(0);
var2 = 3;
block2(0);
   
var3 = 3;
MyBlock block3 = ^(int p)
{
    printf("\nvar3:%d", var3);
};
   
block3(0);
var3 = 4;
block3(0);
   
var4 = 4;
MyBlock block4 = ^(int p)
{
    printf("\nvar4:%d", var4);
};


block4(0);
var4 = 5;
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是成员变量

obj3 = [[TestObjectalloc] init];
printf("\nself retain count:%d", [selfretainCount]);
MyBlock block6 = ^(int p)
{
    printf("\nself retain count:%d", [selfretainCount]);
    printf("\nobj retain count:%d", [obj3retainCount]);
};
block6(0);
printf("\nself retain count:%d", [selfretainCount]);
 



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

obj3 = [[TestObjectalloc] init];
printf("\nself retain count:%d", [selfretainCount]);
MyBlock block7 = ^(int p)
{
    printf("\nself retain count:%d", [selfretainCount]);
    printf("\nobj retain count:%d", [obj3retainCount]);
};
MyBlock block77 = Block_copy(block7);
block7(0); //或者 block77(0);
printf("\nself retain count:%d", [selfretainCount]);
Block_release(block77);
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是局部变量

TestObject *obj4 = [[TestObjectalloc] initWithValue:4];
MyBlock block8 = ^(int p)
{
    printf("\nobj4 retain count:%d", [obj4 retainCount]);
};
MyBlock block88 = Block_copy(block8);
block88(0);
printf("\nobj4 retain count:%d", [obj4 retainCount]);
Block_release(block88);
printf("\nobj4 retain count:%d", [obj4 retainCount]);
 



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

__block TestObject *obj5 = [[TestObjectalloc] initWithValue:5];
MyBlock block9 = ^(int p)
{
    printf("\nobj5 retain count:%d", [obj5 retainCount]);
};
MyBlock block99 = Block_copy(block9);
block99(0);
printf("\nobj5 retain count:%d", [obj5 retainCount]);
Block_release(block99);
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增加。

分享到:
评论

相关推荐

    这是一个基于Objective-C语言的基础案例集。旨在用于给初学者快速了解Objective-C语言的语法。.zip

    Objective-C是一种强大的面向对象编程语言,它主要应用于Apple的iOS和macOS平台...通过逐个研究这些项目,你可以从实践中学习Objective-C,掌握如何创建类、实现方法、进行对象间的通信以及如何构建实际的应用程序。

    Objective-C基础教程(Learn Objective-C)随书源码下载

    Objective-C是C语言的超集,它扩展了C语言,加入了面向对象的特性。面向对象编程(OOP)的核心概念包括类、对象、继承、封装和多态。Objective-C通过消息传递机制实现了这些概念,使得代码更加模块化和可维护。 2....

    Objective-C经典入门源代码

    Objective-C是在C语言的基础上扩展的,因此,它继承了C的语法特性,如变量声明、控制结构(如if-else、for、while)、函数等。同时,它引入了消息传递机制,这是面向对象编程的核心。在Objective-C中,对象通过发送...

    objective-c

    Objective-C是一种面向对象的编程语言,它是C语言的超集,添加了Smalltalk风格的消息传递机制,主要用于开发苹果平台上的应用程序,包括iOS和macOS。Objective-C是在20世纪80年代由Stepanov和Moss在施乐帕洛阿尔托...

    Learn Objective-C Samples.zip

    Objective-C起源于C语言,并在其基础上扩展了面向对象特性。它引入了消息传递机制,使得对象之间的通信更加灵活。在压缩包中的源代码,我们可以看到如何通过方法调用来实现这一机制,如`[someObject performSelector...

    drmoe.tar_Objective-C_

    Objective-C是一种基于C语言的面向对象的编程语言,广泛用于开发iOS和macOS的应用程序。在这个压缩包中,我们看到几个可能的子文件或文件夹: 1. `._just4fun` - 这可能是Mac OS X系统中的元数据文件,通常以"....

    objective-c-lib-source

    Objective-C 是苹果公司...通过对"objective-c-lib-source"的深入研究,开发者可以学习到Objective-C的最佳实践,理解如何构建高效、可维护的iOS应用。同时,对于iOS开发者来说,掌握这些核心概念和框架是必不可少的。

    Objective-C2.0程序设计 答案

    1. **基础语法**:Objective-C基于C语言,因此它保留了C的语法特性,如变量声明、控制结构(if-else,for,while)等。同时,Objective-C引入了Objective-C特有的关键字,如`@interface`,`@implementation`,`@...

    Learn Objective-C Samples.rar

    Objective-C是C语言的超集,增加了Smalltalk式的面向对象特性,如消息传递和类别。 1. **类和对象**:Objective-C中的所有工作都是通过类和对象来完成的。类是对象的蓝图,定义了对象的行为和属性。对象则是类的...

    Objective-C新手入门

    Objective-C的学习不应止步于入门,深入研究Cocoa设计模式、Auto Layout、Core Data、网络编程等高级主题,以及Swift(Apple的现代编程语言)的结合使用,都将有助于提升开发技能。 通过阅读《Objective-C for ...

    十天学会Objective-C 资料.zip

    Objective-C起源于C语言,它在C的基础上添加了面向对象的特性。Objective-C的关键组成部分包括消息传递机制、类和对象、协议以及类别。首先,你需要了解Objective-C的语法基础,如如何定义类,创建对象,以及发送...

    Learn Objective-C Samples

    1. **Objective-C基础**: Objective-C是C语言的超集,这意味着你可以编写任何有效的C代码在Objective-C中。它的扩展主要是为了支持面向对象编程,包括类、继承、消息传递等特性。 2. **类和对象**: 在Objective-C中...

    objective-c2.0 程序题答案

    7. **Blocks**:Objective-C 2.0引入了块(Block),这是一种可以捕获和存储执行上下文的匿名函数。它们在并发编程、回调函数和内存管理中扮演重要角色。 8. **Garbage Collection与Automatic Reference Counting ...

    Examples of Objective-C.zip

    Objective-C是C语言的一个超集,这意味着任何有效的C代码也都是Objective-C代码。它的主要扩展在于引入了Smalltalk式的消息传递机制和类别(categories)、协议(protocols)等特性。下面,我们将深入探讨这些关键...

    IOS应用源码——nluchkin-Sosial-Blocks-497fe69.zip

    【标题】"IOS应用源码——nluchkin-Sosial-...总之,"IOS应用源码——nluchkin-Sosial-Blocks-497fe69.zip"为iOS开发者提供了一个宝贵的资源,可以深入研究社交功能的实现,学习最佳实践,并提升自己的iOS开发技能。

    hAngry-objective-c

    【hAngry-objective-c】项目是一个专注于Objective-C编程语言的开源库,它可能是为了简化iOS和macOS应用开发中的某些常见任务而设计的。在深入探讨这个项目的具体细节之前,我们先了解一下Objective-C的基础知识。 ...

    objc4-818.2.zip

    6. **Blocks与GCD**: Objective-C的Block是一种内联函数对象,它与GCD的结合使得异步编程变得简单。源码中,我们可以看到Block的创建、复制和释放等过程。 7. **异常处理(Exception Handling)**: Objective-C使用...

    objc4-818.zip

    9. **GCD(Grand Central Dispatch)与Blocks**:虽然GCD和Blocks不是Objective-C运行时的一部分,但它们在objc4-818中有所关联,因为Objective-C的Block语法是基于运行时实现的。 通过深入研究objc4-818源码,...

    856754611.zip_操作系统开发_Objective-C_

    Objective-C的语法与C语言兼容,同时增加了Smalltalk式的消息传递机制,这使得它非常适合构建动态和灵活的用户界面。 这个"856754611.zip"压缩包中包含的"ABPadLockScreenDemo"和"ABLockScreen"可能是一个iOS应用的...

Global site tag (gtag.js) - Google Analytics