参考链接:http://www.jianshu.com/p/073db200b285
block: 用copy修饰
delegate:用weak 修饰
堆栈空间分配
堆栈缓存方式
堆栈数据结构区别
------》》》》》》》》》》》》
typedef void(^BlockBack)(NSString *str);
@interface ViewController : UIViewController
- (void)loginWith:(NSString *)str
completion:(BlockBack) block;
@property (nonatomic,copy) BlockBack myBlock;
@property (nonatomic,copy)void(^textBlock)(NSString * str);
Block属性的声明,首先需要用copy修饰符,因为只有copy后的Block才会在堆中,栈中的Block的生命周期是和栈绑定的
Block的定义格式
返回值类型(^block变量名)(形参列表) = ^(形参列表) {
};
调用Block保存的代码
block变量名(实参);
typedefvoid(^BlockType)(int);
//声明属性
@property (copy) BlockType myBlock;
@property (nonatomic, copy) void(^textBlock) (NSString*text); // 字符串回调
@property (nonatomic,copy)dispatch_block_t blockAction; // 点击事件回调
回调值
__weaktypeof(self) weakSelf =self;
vc.v= ^(NSString*str){
weakSelf.textStr=str;
};
//有了atomic来保证基本的原子性还是没有达到线程安全的,调用时需要把Block先赋值给本地变量,以防止Block突然改变。即便是先判断了Block属性不为空,在调用之前,一旦另一个线程把Block属性设空了,程序就会crash:
if(self.myBlock)
{
self.myBlock(123);
}
//先判断其是否为空,self.myBlock可能被另一个线程改为空,造成crash
//注意:atomic只会确保myBlock的原子性,这种操作本身还是非线程安全的
注:循环引用问题
在ARC下,由于__block抓取的变量一样会被Block retain,所以必须用弱引用才可以解决循环引用问题
__weaktypeof(self) weakSelf =self;
self.myBlock= ^()
{
};
对于weak:指明该对象并不负责保持delegate这个对象,delegate这个对象的销毁由外部控制。
对于strong:该对象强引用delegate,外界不能销毁delegate对象,会导致循环引用(Retain Cycles)
对于assing:也有weak的功效。但是网上有assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;而weak一旦不进行使用后,永远不会使用了,就不会产生野指针。