1. 是啥?
是一个静态的函数代码块,其本质是一个指向结构体的指针,可以被当做参数传递
2.怎么用?
2.1 作为函数代码块使用
int(^add)(inta,intb) = ^(inta,inta){//定义了一个名为add的代码块,有两个参数,
return a+b;
};
NSLog(@"%d",add(1,2));//调用代码块
2.2 作为参数传值
@property (nonatomic,copy) void(^cancelBtnEventBlock)();//定义,block一创建是放在栈区的,所以需要用copy将其拷贝到堆区以供其他地方用
if (self.cancelBtnEventBlock) {//调用,只有在调用时才会执行回调的方法
self.cancelBtnEventBlock();
}
self.pickerView.cancelBtnEventBlock = ^(){//回调方法
};
3.什么时候用?
3.1 传值的使用用
3.2 作为代码块的时候用(可以在全局使用)
4.用的时候需要注意什么?
4.1 在使用block时要对block指针做判空处理,否则当指针为空时会造成崩溃。
4.2 在MRC的编译环境下,block如果作为成员参数要先copy一下([myBlock copy])将栈上的block拷贝到堆上。
4.3 在block调用之后要对block指针做赋空值处理(myBlock = nil),如果是MRC的编译环境下,要先release掉block对象([myBlock release],因为之前copy过)再赋空值,以解除循环引用。
4.4 在ARC下,在Block内部使用self或成员变量时要用__weak修饰;MRC下用__block修饰。
4.5 在多线程环境下(block中的weakSelf有可能被析构的情况下),需要先将self转为strong指针,避免在运行到某个关键步骤时self对象被析构。
4.6 若要在块代码内部修改外部变量的数值,需要在定义外部变量的前面用__block修饰(不加__block是值传递,加了之后才是地址传递)
5.其他
回调多于2个,用代理,因为block的可读性低。