您的位置:首页 > 其它

block技术总结-学习笔记

2014-03-03 16:45 190 查看
iOS4.0以后可以使用block技术。

声明一个block:

intmultiplier=7;
int(^myBlock)(int)=^(intnum){

returnnum*multiplier;
};

block可以使用和它相同范围的变量。

声明一个block变量以后,可以想普通函数一样使用该block。

使用__block声明的变量,在block中可以修改。未使用__block声明的变量,在block中只读。

block的优势:1.block可以将当前执行的代码和回调写在一起,更原子性,例如:并且block可以作为函数的参数;2.block可以访问本地变量,例如:直接访问本地变量(如果需要再block中修改,变量需要使用__block关键字声明),在block中做网络请求,将请求返回的数据赋值给上下文中的变量。

在block中可能会有五种变量类型:

  标准的变量:  1.全局变量,包括用static声明的变量;2.全局方法;3.同一代码段的本地变量或参数;

  Block中可以使用的另外两种变量:1.使用__block声明的变量,该变量在block中是可被修改了,如果相关block被拷贝到heap了,那么该变量是被保护的。

                 2.constimport(我觉得这个就是const常量)。

五种变量类型在block中对应的访问规则:  

  1.全局变量:可访问。

  2.参数:可访问(就像普通函数的参数一样)。

  3.临时变量:只读(如果有嵌套block,那么离变量最近的block可以访问该变量)。

  4.使用__block声明的变量:在block中是可以修改的,并且会将修改结果反射到原变量(也就是说,在block中使用的是该变量的引用)。

  5.block内部声明的临时变量:就像普通函数内的临时变量一样。

如果在一个block中通过传引用的方式使用实例变量的话,那么该block对self是强引用的关系;

如果在一个block中通过传值的方式使用实例变量的话(非引用类型:int,float等),那么该block对该实例变量是强引用关系。举例:函数内部的临时变量。

CopyingBlocks

Typically,youshouldn’tneedtocopy(orretain)ablock.Youonlyneedtomakeacopywhenyouexpecttheblocktobeusedafterdestructionofthescopewithinwhichitwasdeclared.Copyingmovesablocktotheheap.

YoucancopyandreleaseblocksusingCfunctions:

  Block_copy();

  Block_release();

Toavoidamemoryleak,youmustalwaysbalanceaBlock_copy()withBlock_release().

PatternstoAvoid

Ablockliteral(thatis,^{...})istheaddressofastack-localdatastructurethatrepresentstheblock.Thescopeofthestack-localdatastructureisthereforetheenclosingcompoundstatement,soyoushouldavoidthepatternsshowninthefollowingexamples:

voiddontDoThis(){

void(^blockArray[3])(void);//anarrayof3blockreferences

    for(inti=0;i<3;++i){

      blockArray[i]=^{printf("hello,%d\n",i);};


//WRONG:Theblockliteralscopeisthe"for"loop.
}

}

voiddontDoThisEither(){

void(^block)(void);

inti=random():
if(i>1000){

block=^{printf("gotiat:%d\n",i);};

//WRONG:Theblockliteralscopeisthe"then"clause.
}

//...}

Debugging

Youcansetbreakpointsandsinglestepintoblocks.YoucaninvokeablockfromwithinaGDBsessionusinginvoke-block,asillustratedinthisexample:

IfyouwanttopassinaCstring,youmustquoteit.Forexample,topassthisstringintothedoSomethingWithStringblock,youwouldwritethefollowing:

$invoke-blockmyBlock1020
$invoke-blockdoSomethingWithString"\"thisstring\""



官方文档里的一段话,说明了什么是block:

BlockFunctionality

Ablockisananonymousinlinecollectionofcodethat:

Hasatypedargumentlistjustlikeafunction

Hasaninferredordeclaredreturntype

Cancapturestatefromthelexicalscopewithinwhichitisdefined

Canoptionallymodifythestateofthelexicalscope

Cansharethepotentialformodificationwithotherblocksdefinedwithinthesamelexicalscope

Cancontinuetoshareandmodifystatedefinedwithinthelexicalscope(thestackframe)afterthelexicalscope(thestackframe)hasbeendestroyed

Youcancopyablockandevenpassittootherthreadsfordeferredexecution(or,withinitsownthread,toarunloop).Thecompilerandruntimearrangethatallvariablesreferencedfromtheblockarepreservedforthelifeofallcopiesoftheblock.AlthoughblocksareavailabletopureCandC++,ablockisalsoalwaysanObjective-Cobject.



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: