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含义不同。
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含义不同。
相关文章推荐
- Enterprise Library 3.0 of Logging Application Block 使用异常解决(记录时间)
- VB.Net 2003 “应用程序生成了一个无法处理的异常”故障分析与解决
- iOS 开发之EXC_BAD_ACCESS异常分析
- iOS中block实现的探究
- Hadoop常见异常分析及解决方法
- Web应用程序访问网络驱动器映射时出现异常分析及其解决办法
- java.lang.ArrayIndexOutOfBoundsException异常分析及解决
- iOS常见异常Exec_Bad_Access问题解决办法
- iOS中block的探究
- ios的Block机制探究
- java.lang.ArrayIndexOutOfBoundsException异常分析及解决
- iOS 开发之EXC_BAD_ACCESS异常分析(转)
- 解决IllegalBlockSizeException:last block incomplete in decryption异常
- 托盘图标异常消失问题的分析与解决
- iOS中block的探究
- java.util.ConcurrentModificationException 异常的基本分析和解决办法
- java.lang.ArrayIndexOutOfBoundsException异常分析及解决
- iOS中block实现的探究
- iOS中block的探究
- IDA反汇编/反编译静态分析iOS模拟器程序(九)block