block实际上就是Objective-C语言对闭包的实现。
- NSString * ( ^ myBlock )( int );
上面的代码声明了一个block(^)原型,名字叫做myBlock,包含一个int型的参数,返回值为NSString类型的指针。
下面来看看block的定义:
myBlock = ^( int paramA )
{
return [ NSString stringWithFormat: @"Passed number: %i", paramA ];
};
上面的代码中,将一个函数体赋值给了myBlock变量,其接收一个名为paramA的参数,返回一个NSString对象。
注意:一定不要忘记block后面的分号。
定义好block后,就可以像使用标准函数一样使用它了:
myBlock(7);
2 block 的使用 : 如果block是一个属性,在调用block的时候,如果block函数体中 调用了 [self did]就出出现循环引用,因为A中有B B中有A 互相调用,就会出现问题,如果block不是属性,则不会出现循环引用,例如:
[UIView animateWithDuration: 0.5 animations: ^{
self.userName.center = accountCenter;
self.password.center = passwordCenter;
self.login.alpha = 1;
} completion: nil];这个为啥会可以使用self,因为这个view不是这个控制器的属性,所以不会又循环引用的问题
如果需要解决循环引用的问题可以
//先声明一个weak弱对象
__weak ViewController *wSelf = self;
[UIView animateWithDuration: 0.5 animations: ^{
//在block的执行过程中,使用强对象对弱对象进行引用
wSelf.userName.center = accountCenter;
wSelf.password.center = passwordCenter;
wSelf.login.alpha = 1;
}
3//声明一个局部整型变量
int intValue = 3;
//声明一个返回值为int,一个int参数的block变量
int (^block)(int) = ^(int m){
intValue++;
return m * intValue;
};
//调用block变量,5作为参数之后的结果
NSLog(@"block(5) = %d",block(5));
在上面的例子中,我们编译程序后发现编译器会有红色错误,错误提示为
Variable is not assignable (missing __block type specifier)
为什么会出现不能被赋值的错误提示呢?
block在实现时就会对它引用到的它所在方法中定义的栈变量进行一次只读拷贝,所以intValue只是可读的,不能操作
在 block 块内使用该只读拷贝。
那为了避免上述错误,就要使用__block修饰符来修饰外部变量,用来通知编译器该外部变量intValue与block中的intValue指的是同一块儿内存地址,而不需要内存拷贝。
所以 __block int intValue = 3;这样才行如果 是 intValue;也会正常运行,