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

发布于 2022-09-02 01:07:15 字数 3873 浏览 15 评论 0

首先我一共有三个页面,分别是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 <Foundation/Foundation.h>

@protocol BaseDelegate <NSObject>

- (void)apiLoadSuccess;

@end


@interface Base : NSObject

@property (nonatomic, weak) id<BaseDelegate>delegate;

@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的地址<Base: 0xc17ecd0>
2016-01-25 16:18:42.190 ARCTest[88322:52655586] 标记1 <Base: 0xc17ecd0>
2016-01-25 16:18:42.190 ARCTest[88322:52655586] 标记2<Base: 0xc17ecd0>
2016-01-25 16:18:42.191 ARCTest[88322:52657228] 标记3<Base: 0xc17ecd0>
2016-01-25 16:18:42.208 ARCTest[88322:52655586] 标记4<Base: 0xc17ecd0>
2016-01-25 16:18:42.209 ARCTest[88322:52655586] 标记5<Base: 0xc17ecd0>
2016-01-25 16:18:42.212 ARCTest[88322:52655586] 跳转到B
2016-01-25 16:18:42.212 ARCTest[88322:52655586] B的地址<Base: 0xc185db0>
2016-01-25 16:18:42.213 ARCTest[88322:52655586] 标记1 <Base: 0xc185db0>
2016-01-25 16:18:42.213 ARCTest[88322:52655586] 标记2<Base: 0xc185db0>
2016-01-25 16:18:42.214 ARCTest[88322:52655586] 销毁了BASE: <Base: 0xc185db0>
2016-01-25 16:18:42.214 ARCTest[88322:52657225] 标记3<Base: 0xc185db0>
2016-01-25 16:18:42.262 ARCTest[88322:52655586] *** -[Base respondsToSelector:]: message sent to deallocated instance 0xc185db0

问题来了。

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文