您的位置:首页 > 移动开发 > IOS开发

ios block探究及block野指针异常报错分析解决

2017-05-25 17:11 375 查看
block一定程度上类似于函数指针,或者说它存储了一个代码块,里面的代码在合适的场合出发调用,所以block的常见应用场景就是回调使用

ios 开发了很久,但是block还没有深入研究过;这位博友文章感觉写的不错,值得借鉴  http://blog.csdn.net/u010130947/article/details/50552910

针对block的一个demo bug说明一下

1.现有ViewController这个controller类,关键代码如下

- (void)viewDidLoad {

    [super viewDidLoad];

    

    TestBlockView *testView = [[TestBlockView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];

    

    testView.backgroundColor = [UIColor lightGrayColor];

    

    __weak UIViewController *weakSelf = self;

    NSString *(^paramBlock)(UIView *) = ^(UIView *view)

    {

                NSLog(@"%@",view);

        

                NSLog(@"%@",weakSelf.view);

                return @"back block str";

    };

    

//    eg.1

//    [testView setResultBlock:^NSString *(UIView *view) {

//        NSLog(@"%@",view);

//        

//        return @"back block str";

//    }];

    

//    eg.2

        [testView setResultBlock:paramBlock];

    

    [self.view addSubview:testView];

}

2.自定义view TestBlockView 关键代码如下

.h 文件

#import <UIKit/UIKit.h>

typedef NSString *(^TestBlockViewBlock)(UIView *view);

@interface TestBlockView : UIView

//properties

@property (strong,nonatomic) TestBlockViewBlock mBlock;

//funcs

-(void)setResultBlock:(TestBlockViewBlock)paramBlock;

@end

.m文件

-(instancetype)initWithFrame:(CGRect)frame

{

    self = [super initWithFrame:frame];

    if (self)

    {

        UILabel *mLabel = [[UILabel alloc] init];

        mLabel.text = @"I am self-created view";

        mLabel.frame = CGRectMake(100, 100, 100, 100);

        [mLabel sizeToFit];

        [self addSubview:mLabel];

        

        UIButton *closeBtn = [[UIButton alloc] init];

        closeBtn.frame = CGRectMake(20, 20, 100, 100);

        [closeBtn setTitle:@"点击" forState:UIControlStateNormal];

        [closeBtn sizeToFit];

        [closeBtn addTarget:self action:@selector(closeClick:) forControlEvents:UIControlEventTouchUpInside];

        [self addSubview:closeBtn];

    }

    return self;

}

-(void)setResultBlock:(TestBlockViewBlock)paramBlock

{

    _mBlock = paramBlock;

}

-(void)closeClick:(UIButton *)btn

{

    _mBlock(btn);

}

在arc(自动引用计数)下,说明如下:

1.当上述代码中橘红色的代码注释掉的时候,此时的block类型为__NSGlobalBlock__,绿色代码处类型是strong weak都可以,因为这个block存储在全局内存块上。

2.当上述代码中橘红色的代码未注释掉的时候,此时的block里面的代码中使用了外部变量,这个block为 NSMallocBlock类型,是存在堆内存上的,和普通堆内存变量一样,需要有强引用才不会被自动销毁,如果绿色出代码为weak类型,淡蓝色出代码会崩溃报错,报野指针异常,因为这个block已经不存在了。所以,此时只有绿色出为strong或者copy才可以。对于NSMallocBlock类型block,copy相当于retain或者说strong,和一般的对象的copy含义不同。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息