block 与 dealloc 的探究

测试用例程序结构:

测试内容: 

在 blockDeallocViewController 中使用了block之后,pop到rootViewController 时是否会调用dealloc函数

测试方法详述: 

blockDeallocViewController .h 全部代码

#import <UIKit/UIKit.h>

@interface BlockTestViewController : UIViewController
{
    UILabel *nameLabel;
    NSInteger ageInt;
    NSMutableArray *nameArray;
}
@property (nonatomic, strong) UILabel *ageLabel;
@property (nonatomic, strong) NSString *nameString;
@property (nonatomic, strong) NSArray *agearray;
@end

blockDeallocViewController .m 部分使用block的代码----subview

<pre name="code" class="objc">__weak BlockTestViewController *weakSelf = self;
__block NSInteger *b_age = &ageInt;
__block NSMutableArray *__nameArray = nameArray;
__block UILabel *__nameLabel = nameLabel;
DetailView *detailView = [[DetailView alloc] initWithFrame:CGRectMake(0, 0, 200, 50)];
[detailView setCenter:CGPointMake(self.view.center.x, self.view.center.y + 100)];
[detailView setBlockTest:^(NSString *name, NSInteger age) {
     *b_age = age;
     [__nameArray removeObjectAtIndex:age];
     [__nameLabel setText:name];
     weakSelf.nameString = name;
     [weakSelf.ageLabel setText:[NSString stringWithFormat:@"%d",age]];
     weakSelf.agearray = @[@"string"];
}];
[self.view addSubview:detailView];

 

1.这里的detailView就是图中的subview

2.全局变量  nameLabel、ageInt、nameArray

3.这里的ageInt最奇葩,他是NSInteger类型,非对象非指针,要想修改他的值还要保证 引用计数 不增加,取他的地址给 __block 修饰的 *b_age

4.对于@property ageLabel、nameString、agearray ,既要正确的引用又不能增加引用计数,用__weakSelf取用即可

5.上述用法不会影响dealloc的调用

6.为什么属性可以用 __weakSelf.nameString 这样的形式调用,因为对property 赋值相当于调用setter方法,也就是__weakSelf.nameString其实是[__weakSelf setNameString]

blockDeallocViewController .m 部分使用block的代码----push new viewController

__block NSInteger age_int = 0;
ThirdViewController *thirdViewController = [[ThirdViewController alloc] init];
[thirdViewController setNameString:_nameString];
[thirdViewController setBlockTest:^(NSString *name, NSInteger age) {
    _nameString = name;
    ageInt = age;
    age_int = age;
    [nameArray removeObjectAtIndex:age];
    [nameLabel setText:name];
    [_ageLabel setText:[NSString stringWithFormat:@"%d",age]];
    _agearray = @[@"string"];
    NSLog(@"%@",self);
}];
[self.navigationController pushViewController:thirdViewController animated:YES];


1.这里对全局变量和property属性的用法和在block之外是一样的

2.这样用并没有影响dealloc函数的调用

3.原因:那是因为当pop thirdViewController 的时候,thirdViewController调用了dealloc,既thirdViewController被释放了,所以该block对self的引用都释放掉了,所以没有影响blockDeallocViewController dealloc的调用

4.验证:对subview 做这个处理:

    [detailView removeFromSuperview];

    detailView = nil;

也就是把detialView释放掉,会发现原先会增加循环计数的代码,也不能影响blockDeallocViewController dealloc的调用了

结论:

1.block 里面不要使用 self,用 __weak 转换 self 为弱引用指针

2.全局变量用__block修饰后再放到block使用
3.使用property属性,用__weakSelf

4.如果可以,用完后把block释放掉


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值