__block int a= 10; /* *block 中使用局部变量的时候 不能修改它的值(readonly) 如果需要修改 在局部变量申明的时候用 __block 来修饰 */ //定义一个block 和 实现部分
int (^TTblocke)(int) = ^(int num){ ++a; return num * a; }; NSLog(@"%d",TTblocke(3));
block 做反向传值 ----- A界面 跳转 B界面----------由B界面向A界面传递数据
1.在B界面声明一个block的属性
#import <UIKit/UIKit.h> @interface NextViewController : UIViewController @property(nonatomic,strong)void(^callback)(NSString *,int); @end
2. 在A界面跳转下一个页面的位置 实现block
NextViewController *next = [[NextViewController alloc]init]; next.callback = ^(NSString *reslt,int t) { NSLog(@"%@+++%d",reslt,t); }; [self presentViewController:next animated:YES completion:nil];
3. 在B界面需要传递数据的位置 写入需要传递的数据
-(void)buttonClick:(UIButton *)sender { [self dismissViewControllerAnimated:YES completion:^{ self.callback(@"dcsdf",90); }]; }
使用block时不能造成循环引用。
循环引用指两个对象相互强引用了对方,即retain了对方,从而导致谁也释放不了谁的内存泄露问题。(如声明一个delegate时一般用assign而不能用retain或strong)
注意一:
局部自动变量,在Block中只读。Block定义时copy变量的值,在Block中作为常量使用,所以即使变量的值在Block外改变,也不影响他在Block中的值
注意二:
STATIC修饰符的全局变量,因为全局变量或静态变量在内存中的地址是固定的,Block在读取该变量值的时候是直接从其所在内存读出,获取到的是最新值,而不是在定义时copy的常量.
@interface ViewController () @property(nonatomic,strong)void (^myBlock)(); @end self.myBlock = ^(){ [self doingSomeThing]; }; -(void)doingSomeThing { NSLog(@"doingSomeThing"); }
这样写就造成了 return cycle(循环引用)
经过测试 吧代码修改成下面的
__block ViewController *weakSelf = self; self.myBlock = ^(){ [weakSelf doingSomeThing]; };
还是存在循环引用问题 所以 __block 不能很好的解决问题
把代码在修改一下
__weak ViewController *weakSelf = self; self.myBlock = ^(){ [weakSelf doingSomeThing]; };
或者
__unsafe_unretained ViewController *weakSelf = self; self.myBlock = ^(){ [weakSelf doingSomeThing]; };
这样就可以避开循环引用问题
为了方便 可以将 弱引用申明写成宏形式
#define WeakSelf __weak typeof(self) weakSelf = self; 这样就不用再每次使用block会出现循环引用的时候都去写
__weak ViewController *weakSelf = self;
进一步方便其他的强引用对象在block中方便使用可以将宏定义修改成(带参宏)
#define WeakObj(o) __weak typeof(o) o##Weak = o;
在使用前 先 WeakObj(self) 申明一次 然后就可以用 selfWeak 这个对self的弱引用来解决循环引用的问题