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

关于使用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 <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运行到一半销毁掉了,然后造成僵尸对象崩溃了,如何解决呢?

【热门文章】
【热门文章】