1、block的使用
//
简单的使用
block
这一步是声明和定义 变量名:
easyBlock
返回int型;参数类型int型
int
(^easyBlock)(
int
,
int
)=^(
int
a,
int
b){
return
a + b;
};
int
result;
//
这里是
block
的使用,需要传两个参数上去
result = easyBlock(
2
,
5
);
NSLog
(
@"result is %d"
,result);
int
(^myBlock)(
int
,
int
)=^(
int
m,
int
n){
return m - n ;
};
result = myBlock( 10 , 1 );
NSLog ( @"%d" ,result);
return m - n ;
};
result = myBlock( 10 , 1 );
NSLog ( @"%d" ,result);
2、
/*
局部的基本数据类型变量,进入到 block 中, num 会变成常量。如果需要在 block 中对 num 进行修改,需要加上关键字 __block ( 我们也可以用 static 关键字进行修饰 )
局部的基本数据类型变量,进入到 block 中, num 会变成常量。如果需要在 block 中对 num 进行修改,需要加上关键字 __block ( 我们也可以用 static 关键字进行修饰 )
*/
__block int num = 10;
MyBlock block1 = ^{
NSLog(@"num is %d", num);
//
当没有加上
__block
时,错误,不能对常量进行自加操作
num++;
};
num = 20;
block1();
NSLog(@"num is %d", num);
3、
局部的OC对象进入到block时, 该对象会被retain一次(注意: block在堆区上时才会起到retain作用
NSObject
*obj = [[
NSObject
alloc
]
init
];
NSLog
(
@"%ld"
, obj.
retainCount
);
MyBlock block2 = ^{
NSLog ( @"%ld" , obj. retainCount );
};
[block2 copy ];
block2();
__block Person *ps = [[ Person alloc ] init ];
MyBlock block3 = ^{
NSLog ( @"%ld" , ps. retainCount );
};
MyBlock block2 = ^{
NSLog ( @"%ld" , obj. retainCount );
};
[block2 copy ];
block2();
__block Person *ps = [[ Person alloc ] init ];
MyBlock block3 = ^{
NSLog ( @"%ld" , ps. retainCount );
};
[block3 copy];
block在堆区上时才会起到retain作用
Block_copy
(block3);
block3();
[ps release ];
block3();
[ps release ];
[block3 release];一般copy了就要记得release
Block_release
(block3);
4、解决循环引用的问题
第一种循环引用:类内部的循环引用
实例变量:
演示实例变量
注意:在person的声明文件中,有一个实例变量 NSobject *
personObject;
如果按照常规的写法,但是当实例变量进入到block时会使它所在的变量retain
personObject = [[NSObject alloc] init];
self
.
myBlock
= ^{
self->myBlock->self 导致循环引用 NSLog(@"%ld",personObject.retainCount);
解决方法1:用中间变量
_personObject = [[NSObject alloc] init];
__block NSObject *obj = _personObject;
//演示第一种循环引用,并解决(通过中间变量解决)
__block
Person
*ps =
self
;
//self -> myblock -> self( 并不是 _personObject)
//self -> myblock -> self
self . myBlock = ^{
NSLog ( @"%ld" , ps-> _personObject . retainCount );
// [ps testFun1];
};
//self -> myblock -> self( 并不是 _personObject)
//self -> myblock -> self
self . myBlock = ^{
NSLog ( @"%ld" , ps-> _personObject . retainCount );
// [ps testFun1];
};
_myBlock();
第二种循环引用:外部的循环引用
__block
Person
*ps = [[Person alloc] init];
//ps->myBlock->ps
ps. myBlock = ^{
[ps testFun ];
};
ps. myBlock ();
//ps->myBlock->ps
ps. myBlock = ^{
[ps testFun ];
};
ps. myBlock ();
[ps release];
在ARC中__block 修饰的指针由常量指针变为可变指针,
在ARC中,
__block关键字不能解决循环引用的问题,一般是按照如下的方法进行的
__weak
RootViewController
*rootVC =
self
;
BaseButton *btn = [[ BaseButton alloc ] initWithFrame : CGRectMake ( 100 , 100 , 50 , 50 ) WithBlock :^( UIButton *btn) {
RootViewController *strongRoot = rootVC;
//push 到下一级界面
SecondViewController *secondVC = [[ SecondViewController alloc ] init ];
[strongRoot. navigationController pushViewController :secondVC animated : YES ];
// [secondVC release];
}];
BaseButton *btn = [[ BaseButton alloc ] initWithFrame : CGRectMake ( 100 , 100 , 50 , 50 ) WithBlock :^( UIButton *btn) {
RootViewController *strongRoot = rootVC;
//push 到下一级界面
SecondViewController *secondVC = [[ SecondViewController alloc ] init ];
[strongRoot. navigationController pushViewController :secondVC animated : YES ];
// [secondVC release];
}];