测试用例程序结构:
测试内容:
在 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];
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释放掉