php 多线程释放内存,内存管理,_关于使用block和多线程导致的内存问题,内存管理 - phpStudy...

本文分析了一个iOS应用中,通过block和多线程操作引发的内存问题,BViewController在执行过程中意外销毁,导致AViewController的Base对象成为僵尸对象。通过代码示例和日志追踪,探讨了内存管理问题及解决策略。

关于使用block和多线程导致的内存问题

首先我一共有三个页面,分别是AViewController、BViewController、Base

AViewController.h的源码如下:

#import "Base.h"

#import "ViewController.h"

@interface AViewController : UIViewController

@property (nonatomic, strong) Base *aBase;

@end

AViewController.m的源码如下:

#import "AViewController.h"

#import "BViewController.h"

@implementation AViewController

- (void)viewDidLoad {

[super viewDidLoad];

self.aBase = [[Base alloc] init];

NSLog(@"A的地址%@", self.aBase);

self.title = @"A";

[self.aBase ApiPOST:^{

}];

BViewController *vc = [[BViewController alloc] init];

[self.navigationController pushViewController:vc animated:YES];

}

- (void)dealloc

{

NSLog(@"销毁了A");

}

@end

BViewController.h的源码如下:

#import "ViewController.h"

@interface BViewController : UIViewController

@end

BViewController.m的源码如下:

#import "BViewController.h"

#import "Base.h"

@implementation BViewController

- (void)viewDidLoad {

[super viewDidLoad];

self.title = @"B";

NSLog(@"跳转到B");

[self run];

}

- (void)run

{

Base *base = [[Base alloc] init];

NSLog(@"B的地址%@", base);

[base ApiPOST:^{

}];

}

@end

Base.h的源码如下:

#import

@protocol BaseDelegate

- (void)apiLoadSuccess;

@end

@interface Base : NSObject

@property (nonatomic, weak) iddelegate;

@property (nonatomic) NSInteger limitNum;

@property (nonatomic) NSInteger offset;

typedef void (^apiBlock)();

- (void)ApiPOST:(apiBlock)block;

@end

Base.m的源码如下:

#import "Base.h"

@implementation Base

- (void)ApiPOST:(apiBlock)block

{

__unsafe_unretained __typeof(self) weakSelf = self;

NSLog(@"标记1 %@", self);

[self POST:^{

[weakSelf apiLoadSuccess];

}];

}

- (void)POST:(apiBlock)block

{

NSLog(@"标记2%@", self);

__unsafe_unretained __typeof(self) weakSelf = self;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

NSLog(@"标记3%@", weakSelf);

dispatch_async(dispatch_get_main_queue(), ^{

NSLog(@"标记4%@", weakSelf);

if (block) {

block();

}

});

});

}

- (void)apiLoadSuccess

{

NSLog(@"标记5%@", self);

if (self.delegate && [self.delegate respondsToSelector:@selector(apiLoadSuccess)]) {

[self.delegate apiLoadSuccess];

}

}

- (void)dealloc

{

NSLog(@"销毁了BASE: %@", self);

}

@end

运行时,日志如下:

2016-01-25 16:18:42.188 ARCTest[88322:52655586] A的地址

2016-01-25 16:18:42.190 ARCTest[88322:52655586] 标记1

2016-01-25 16:18:42.190 ARCTest[88322:52655586] 标记2

2016-01-25 16:18:42.191 ARCTest[88322:52657228] 标记3

2016-01-25 16:18:42.208 ARCTest[88322:52655586] 标记4

2016-01-25 16:18:42.209 ARCTest[88322:52655586] 标记5

2016-01-25 16:18:42.212 ARCTest[88322:52655586] 跳转到B

2016-01-25 16:18:42.212 ARCTest[88322:52655586] B的地址

2016-01-25 16:18:42.213 ARCTest[88322:52655586] 标记1

2016-01-25 16:18:42.213 ARCTest[88322:52655586] 标记2

2016-01-25 16:18:42.214 ARCTest[88322:52655586] 销毁了BASE:

2016-01-25 16:18:42.214 ARCTest[88322:52657225] 标记3

2016-01-25 16:18:42.262 ARCTest[88322:52655586] *** -[Base respondsToSelector:]: message sent to deallocated instance 0xc185db0

问题来了。

为什么B运行到一半销毁掉了,然后造成僵尸对象崩溃了,如何解决呢?

相关阅读:

Mac 用git提交代码缺少多级目录的代码!服务器是https模式!

[typecho]获取 父级分类 名称?

Java怎么模拟登录亚马逊中国网站

BOOL变量在if条件语句的理解(OC)

java RandomAccessFile 覆盖数据

一个sed的写法疑问

Xcode 的 Size Class 在实际开发中的使用率高吗?

怎么让页面在不同分辨率的电脑都能显示?

为什么析构函数什么也不写仍然会delete其成员指针?

超出div宽度范围的文字进行省略号省略,如何在鼠标移上去以后显示完整的内容?

对DNS的一些简单理解

bootstrap插件的写法疑问(2)。

uc浏览器 访问是去掉了Referer

QQ互联的回调地址怎么填写?

七牛提供的域名不能访问

ScrollView掛载,为什么会很久才会显示画面

Java后台的controller在知道一个绝对路径的情况下,如何下载该文件?

webpack的 extract text plugin for webpack 报错怎么回事?

python中浮点数使用int()的问题

peewee postgres ArrayField 和JSONField怎么update数据

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值