iOS学习

认识block以及注意事项。

2017-11-21  本文已影响11人  Macalk
block.png

1、声明一个block

带参数
typedef void(^nameBlock)(int one,int two);
不带参数
typedef void(^nameBlock)(void);

2、创建一个(property)block参数(block 使用copy修饰符)

typedef void(^nameBlock)(int one,int two);
@property (nonatomic,copy) nameBlock name;
或
@property (nonatomic,copy) void(^nameBlock)(int one,int two);

3、创建一个以block为参数的方法(以自定义弹出框为例)

- (void)createAlertVCWithTitle:(NSString *)title andMessage:(NSString *)message andDefultActionTitle:(NSString *)defultActionTitle andDefultAciton:(void(^)(UIAlertAction *action))defultAction andCancelActionTitle:(NSString *)cancelActionTitle andCancelAction:(void(^)(UIAlertAction *action))cancelAction {
    UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *actionOne = [UIAlertAction actionWithTitle:defultActionTitle style:UIAlertActionStyleDefault handler:defultAction];
    UIAlertAction *actionTwo = [UIAlertAction actionWithTitle:defultActionTitle style:UIAlertActionStyleDefault handler:cancelAction];
    
    [alertVC addAction:actionOne];
    [alertVC addAction:actionTwo];
    [self.navigationController presentViewController:alertVC animated:YES completion:nil];
}

4、使用block传递button的点击事件
例如自定义CustomView继承与UIView,并添加UIButton
.h

@interface CustomView : UIView
@property (nonatomic,copy) buttonBlock btnBlock;
- (void)createBlockMethod:(buttonBlock)block;
@end

.m

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor yellowColor];
        
        for (int i = 0; i<3; i++) {
            UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
            btn.tag = 10+I;
            btn.backgroundColor = [UIColor orangeColor];
            btn.frame = CGRectMake(10, 10+(60)*i, self.bounds.size.width-20, 50);
            [btn setTitle:[NSString stringWithFormat:@"第%d行",i] forState:normal];
            [self addSubview:btn];
            [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
        }
    }
    return self;
}
- (void)createBlockMethod:(buttonBlock)block {
    self.btnBlock = block;
}
- (void)btnClick:(UIButton *)sender {
    self.btnBlock(sender);
}

在ViewController.m里实例化CustiomView

#import "ViewController.h"
#import "CustomView.h"
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
CustomView *customView = [[CustomView alloc]initWithFrame:CGRectMake(150, 300, 100, 200)];
    [customView createBlockMethod:^(UIButton *sender) {
        NSLog(@"这是啥---->%ld",sender.tag);
    }];
    [self.view addSubview:customView];
}
@end

注意:如果在block里要修改局部变量需要在使用__block修饰该变量 (全局变量则不需要)例如:

- (void)viewDidLoad {
    [super viewDidLoad];

int __block a = 10;
    self.block = ^(NSString *str) {
        a = 20;
    };
}

避免block的循环引用,如果A持有B,B中持有A则会造成循环引用(A<->B)引起内存泄漏,例如(当前类持有一个叫block的属性,而block里又持有当前类的属性):


WechatIMG165.jpeg

这时候需要对self进行弱引用(即使用__weak修饰self,形成弱引用)。如果name属性并不是当前self的属性,则不会引起循环引用,主要是告诉大家,不用见到block块就使用弱引用。


WechatIMG166.jpeg

既然说到了__weak的使用,那就在说说__weak和__strong的区别

__weak typeof(self) weakSelf = self; //我们根据typeof()括号里面的变量,自动识别变量类型并返回该类型。
    self.block = ^(NSString *str) {
        
        __strong __typeof(self) strongSelf = weakSelf;
        strongSelf.name = @"测试";
        strongSelf.name = @"测试";
        strongSelf.name = @"测试";

    };

__strong 确保在 Block 内,strongSelf 不会被释放。
总结
(1) 在 Block 内如果需要访问 self 的方法、变量,建议使用 weakSelf。
(2) 如果在 Block 内需要多次 访问 self,则需要使用 strongSelf。

上一篇 下一篇

猜你喜欢

热点阅读