iOS内存话题: 实例变量造成的循环引用
来源:互联网 发布:js验证用户名 编辑:程序博客网 时间:2024/04/28 23:06
OC 中关于成员变量和属性的区别, 在阅读下面内容之前请自行 google.
工程目录如下
示例较简单, ViewController 直接打开 CoreViewController.
完整例子下载, 请戳这里!
Person.h
#import <Foundation/Foundation.h>typedef void(^PlayFunction)(int x);@interface Person : NSObject@property (strong, nonatomic) PlayFunction playBlock;@end
Person.m
没有任何实现.
ViewController.m
#import "ViewController.h"#import "CoreViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{ [super viewDidLoad]; CoreViewController *page = [CoreViewController new]; [self.navigationController pushViewController:page animated:YES];}@end
#import "CoreViewController.h"#import "Person.h"@interface CoreViewController (){ BOOL isKill;}@property (strong, nonatomic) Person *person;@end@implementation CoreViewController- (void)dealloc{ NSLog(@"CoreViewController dealloc");}- (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor grayColor]; _person = [[Person alloc] init]; _person.playBlock = ^ void (int x) { isKill = NO; };}@end
编译运行, 在 CoreViewController 返回的时候, 我们发现其 dealloc 方法并没有被调用.
接下来, 我们注释掉 playBlock 里面的这句
isKill = NO;
再编译运行, 发现 dealloc 方法被调用了.
也就是说, 原因在于 isKill 这个实例变量上面.
Person 是 CoreViewController 的强引用, 而 Person 的 block 属性对 CoreViewController也是强引用.
那么, 大家会说了, 修改 Person.h
#import <Foundation/Foundation.h>typedef void(^PlayFunction)(int x);@interface Person : NSObject@property (copy, nonatomic) PlayFunction playBlock;@end
发现还是不行.将 copy 改为 weak 吧, 没错, 这样的确可以.
但是, 你会看到编译器不高兴了.
看来这样不妥.
可能你会说, 在 ViewController 中将 person 改为 weak,
@property (weak, nonatomic) Person *person;
的确可以这么解决不释放的问题, 但是也有警告
那我们再换一种方式,
- (void)viewDidLoad{ [super viewDidLoad]; self.view.backgroundColor = [UIColor grayColor]; _person = [[Person alloc] init]; CoreViewController __weak *weakSelf = self; _person.playBlock = ^ void (int x) { CoreViewController __strong *strongSelf = weakSelf; strongSelf->isKill = NO; };}
完美解决.
这里啰嗦一下, 千万不要使用 weakSelf 访问实例变量, 否则编译报错.
推荐阅读:
到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf
正确使用Block避免Cycle Retain和Crash
1 0
- iOS内存话题: 实例变量造成的循环引用
- iOS容易造成循环引用的三种场景,(循环引用),内存泄漏
- iOS 容易造成循环引用的场景
- iOS内存话题: 弱引用下的懒加载
- iOS中造成循环引用的集中情况
- iOS容易造成循环引用的三种场景
- iOS容易造成循环引用的三种场景
- iOS中容易造成循环引用的三种场景
- 【转】iOS容易造成循环引用的三种场景
- iOS容易造成循环引用的三种场景
- iOS容易造成循环引用的三种场景
- 造成循环引用的情况
- iOS内存循环引用
- iOS开发--Block容易造成循环引用
- weak_ptr 弱引用打破智能指针中循环引用造成的内存泄露
- NSTimer造成循环引用的问题
- iOS容易造成循环引用的三种场景之Block以及对应的使用方法(二)
- iOS容易造成循环引用的三种场景NSTimer以及对应的使用方法(一)
- struts2入门到精通教程
- Spring3.1集成Quartz,让你的任务执行随心所欲
- HDU 1297 Children’s Queue
- 关于接口,继承,内部类的一些测试
- Java线程池——FutureTask
- iOS内存话题: 实例变量造成的循环引用
- STL之常用算法
- php里面的MySql
- 为啥你手机还用不上安卓6.0?
- vim cuda语法高亮
- jdk动态代理
- opencv画图的几个函数例程
- HUTACM2016 MST练习·解题报告
- WPF+MVVM插件化架构-壳