block 被Object-C看成一个对象,它封装了一段代码,这段代码可以在任何时候执行,提高程序的阅读性和复用性,相当于C语言中的指针,是一种方法回调机制。是对C语言的扩展,用来实现匿名内部函数的特性,可以实现函数的嵌套,访问函数内部变量。
在类中定义一个block变量,就像定义一个函数。block定义在函数内部,可以把它当作私有函数,定义在函数外部,其实就是文件级别的全局变量 。
Block 可以作为函数参数或者函数返回值,而其本身也可以带输入参数或返回值。
};
对于非ARC下, 为了防止循环引用, 我们使用__block来修饰在Block中使用的对象:
对于ARC下, 为了防止循环引用, 我们使用__weak来修饰在Block中使用的对象。ARC中,Block中如果引用了__strong修饰符的自动变量,则相当于Block对该变量的引用计数+1
NSString *_string;
_block = ^(){
NSLog(@string %@, _string);
};
这里的_string相当于是self->_string;那么block是会对内部的对象进行一次retain。也就是说,self会被retain一次。当self释放的时候,需要block释放后才会对self进行释放,但是block的释放又需要等self的dealloc中才会释放。如此一来变形成了循环引用,导致内存泄露。
修改方案
__block ViewController *controller = self;
_block = ^(){
NSLog(@string %@, controller->_string);
};
typedefvoid (^myBlock)(int a,int b,int c,int d);
@interface ViewController :UIViewController
-(void)loadFinished:(myBlock)block value1:(int)x value2:(int)y;
@property (strong,nonatomic)myBlock myblock;
@end
-(void)loadFinished:(myBlock)block value1:(int)x value2:(int)y;
{
self.myblock = [blockcopy];
self.myblock(x+y,x-y,x*y,x/y);
}
self.m_viewctrl = [[ViewControlleralloc] init];
//两种 方法实现block
// void (^myBlock)(int a,int b,int c,int d)=^(int a,int b,int c,int d)
// {
// NSLog(@"\n a = 3\n b = 2\n那么: \n a+b = %d \n a-b = %d \n a*b = %d\n a/b = %d\n",a,b,c,d);
// };
-------------
myBlock mblock=^(int a,int b,int c,int d)
{
NSLog(@"\n a = 3\n b = 2\n那么: \n a+b = %d \n a-b = %d \n a*b = %d\n a/b = %d\n",a,b,c,d);
};
[self.m_viewctrlloadFinished:mblock value1:3value2:2];