iOS 笔记之 Block
来源:互联网 发布:腾讯云怎么解析cn域名 编辑:程序博客网 时间:2024/06/02 19:35
介绍一下OC中,ARC模式,使用block引起循环引用的问题
先写结论:(直接贴下面的代码,结论在此代码中)
- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor yellowColor]; NSLog(@"address:%p",self); __weak typeof(self) weakSelf = self; <span style="color:#ff0000;">/* *(一) * * 使用 Block 的对象 作为: * 成员变量 * 结论:作为成员变量的时候,self参与持有,所以可能形成(self->blockObj->block->self)三者的循环引用 * 解决方式: * 对 self 和 成员变量使用:__weak */ /*</span> self.testObj = [[TestBlock alloc] init]; [self.testObj testCallWithBlock:^(id result) { // (1) leak [self & TestBlock] //id obj = self.testObj; //NSLog(@"address_block:%p",obj); // (2) leak [self & TestBlock] //id obj = self; //NSLog(@"address_block:%p",obj); // (3) unLeak //NSLog(@"testCallWithBlock_end"); // (4) unLeak //id obj = weakSelf; //NSLog(@"address_block:%p",obj); // (5) unLeak //id obj = weakSelf.testObj; //NSLog(@"address_block:%p",obj); }]; */ <span style="color:#ff0000;">/* *(二) * * 使用 Block 的对象 作为: * 局部变量 * 结论:作为局部变量的时候,self不参与持有,所以self不会形成循环引用,但是, * 局部变量可能引用自己,形成循环引用(下面情形(1))。 * 解决方式: * 对此局部变量使用 __weak */</span> TestBlock *tempTestObj = [[TestBlock alloc] init]; __weak typeof(tempTestObj) weakBlockObj = tempTestObj; [tempTestObj testCallWithBlock:^(id result) { // (1) leak [TestBlock] //id obj = tempTestObj; //NSLog(@"address_block:%p",obj); // (2) unLeak id obj = weakBlockObj; NSLog(@"address_block:%p",obj); // (3) unLeak //id obj = self; //NSLog(@"address_block:%p",obj); // (4) unLeak //NSLog(@"testCallWithBlock_end"); // (5) unLeak //id obj = weakSelf; //NSLog(@"address_block:%p",obj); }];}
完整测试代码如下:
//// ViewController.m// BlockTest//// Created by liuchaoran on 15/3/19.// Copyright (c) 2015年 liuchaoran. All rights reserved.///* * 测试思路: * 创建另一个 TestViewController,展示这个界面 2 秒,再 dismiss 此界面。 * (如果单纯这样一个空的 TestViewController ,在 dismiss 的时候,毫无疑问是要被释放的,不解释)。 * 在 TestViewController 创建成功后马上调用 TestBlock ,TestBlock 3 秒返回。 * 也就是说,TestBlock 在 TestViewController 消失之后才返回结果,这时候看一下 TestBlock 和 TestViewController 是否被释放。 */#import "ViewController.h"#import "TestViewController.h"@interface ViewController ()@property(nonatomic,strong)TestViewController *testVc;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. self.view.backgroundColor = [UIColor whiteColor]; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(50, 100, 200, 50); [button setTitle:@"推出下个页面" forState:UIControlStateNormal]; [button setBackgroundColor:[UIColor blackColor]]; [button addTarget:self action:@selector(pushNext) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; TestViewController *tv = [[TestViewController alloc] init]; self.testVc = tv;}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)pushNext{ NSLog(@"pushNext_start"); [self presentViewController:self.testVc animated:NO completion:^{ NSLog(@"presentViewController_present_complete"); }]; [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(popNext) userInfo:nil repeats:NO];}-(void)popNext{ NSLog(@"popNext_start"); [self.testVc dismissViewControllerAnimated:NO completion:^{ NSLog(@"presentViewController_dismiss_complete"); }]; self.testVc = nil;}@end
//// TestViewController.m// BlockTest//// Created by liuchaoran on 15/3/19.// Copyright (c) 2015年 liuchaoran. All rights reserved.//#import "TestViewController.h"#import "TestBlock.h"@interface TestViewController ()@property(nonatomic,strong)TestBlock *testObj;@end@implementation TestViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.view.backgroundColor = [UIColor yellowColor]; NSLog(@"address:%p",self); __weak typeof(self) weakSelf = self; /* *(一) * * 使用 Block 的对象 作为: * 成员变量 * 结论:作为成员变量的时候,self参与持有,所以可能形成(self->blockObj->block->self)三者的循环引用 * 解决方式: * 对 self 和 成员变量使用:__weak */ /* self.testObj = [[TestBlock alloc] init]; [self.testObj testCallWithBlock:^(id result) { // (1) leak [self & TestBlock] //id obj = self.testObj; //NSLog(@"address_block:%p",obj); // (2) leak [self & TestBlock] //id obj = self; //NSLog(@"address_block:%p",obj); // (3) unLeak //NSLog(@"testCallWithBlock_end"); // (4) unLeak //id obj = weakSelf; //NSLog(@"address_block:%p",obj); // (5) unLeak //id obj = weakSelf.testObj; //NSLog(@"address_block:%p",obj); }]; */ /* *(二) * * 使用 Block 的对象 作为: * 局部变量 * 结论:作为局部变量的时候,self不参与持有,所以self不会形成循环引用,但是, * 局部变量可能引用自己,形成循环引用(下面情形(1))。 * 解决方式: * 对此局部变量使用 __weak */ TestBlock *tempTestObj = [[TestBlock alloc] init]; __weak typeof(tempTestObj) weakBlockObj = tempTestObj; [tempTestObj testCallWithBlock:^(id result) { // (1) leak [TestBlock] //id obj = tempTestObj; //NSLog(@"address_block:%p",obj); // (2) unLeak id obj = weakBlockObj; NSLog(@"address_block:%p",obj); // (3) unLeak //id obj = self; //NSLog(@"address_block:%p",obj); // (4) unLeak //NSLog(@"testCallWithBlock_end"); // (5) unLeak //id obj = weakSelf; //NSLog(@"address_block:%p",obj); }];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}-(void)dealloc{ NSLog(@"TestViewController_dealloc");}@end
//// TestBlock.h// BlockTest//// Created by liuchaoran on 15/3/19.// Copyright (c) 2015年 liuchaoran. All rights reserved.//#import <Foundation/Foundation.h>typedef void (^myBlock)(id result);@interface TestBlock : NSObject@property(nonatomic,strong)myBlock completionBlock;-(void)testCallWithBlock:(myBlock)returnBlock;@end
//// TestBlock.m// BlockTest//// Created by liuchaoran on 15/3/19.// Copyright (c) 2015年 liuchaoran. All rights reserved.//#import "TestBlock.h"@implementation TestBlock-(void)dealloc{ NSLog(@"TestBlock_dealloc");}-(void)testCallWithBlock:(myBlock)returnBlock{ self.completionBlock = [returnBlock copy]; [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(end) userInfo:nil repeats:NO];}-(void)end{ if (self.completionBlock) { self.completionBlock(@"shit"); }}@end
0 0
- iOS 笔记之 Block
- iOS 笔记之block
- iOS 初学笔记之Block语法基础
- ios学习笔记之block在ios开发中的应用
- ios学习笔记之block在ios开发中的应用
- ios学习笔记之block在ios开发中的应用
- ios学习笔记之block在ios开发中的应用
- iOS开发笔记--iOS之轻松上手block
- ios学习笔记之block在ios开发中的应用
- iOS Block 学习笔记
- IOS学习笔记-Block
- ios block 笔记
- IOS Block 笔记
- iOS笔记---Block
- 【iOS学习笔记】block
- iOS 笔记七:block
- ww笔记-iOS之代码块(block)的使用
- IOS学习笔记之九:block的应用
- poj 2182 Lost Cows
- Oracle to_char函数的使用方法
- hihoCoder37周 分治 O(n)第k大数~
- 2015.3.19三角形类
- 取精华、去糟粕!适合iOS开发者的15大网站推荐
- iOS 笔记之 Block
- 深入理解HTTP协议及原理分析之基础概念篇1
- 预编译语句替换NSLog提高性能
- mysql入门加深入
- 【bzoj 3598】: [Scoi2014]方伯伯的商场之旅
- ubuntu11.04 更新版本(其他的老版本都是相似的)(不能使用apt-get update)
- 位段介绍
- 35.Search Insert Position
- 30岁问题或者只是一个浮云