关于copy形式下block的内存泄漏问题

在分析这个问题之前,我们先列出下面这个图,并且理清它们的关系:

    

这里的setting控制器是指:ILSettingViewController,它在.h文件中定义了一个数组变量

@interface ILSettingViewController: UIviewViewController <UITableViewDataSource, UITableViewDelegate>
{
    NSMutableArray *_allGroups; // 所有的组模型
}
@end

_allGroups存放的是ILSettingGroup对象,ILSettingGroup.h文件代码如下:


//  ILSettingGroup.h
#import <Foundation/Foundation.h>


@interface ILSettingGroup : NSObject
@property (nonatomic, copy) NSString *header; // 头部标题
@property (nonatomic, copy) NSString *footer; // 尾部标题
@property (nonatomic, strong) NSArray *items; // 中间的条目

@end


ILSettingGroup的items数组存放的是ILSettingItem对象,ILSettingItem的.h文件为


#import <Foundation/Foundation.h>


typedef enum {
    ILSettingItemTypeNone, // 什么也没有
    ILSettingItemTypeArrow, // 箭头
    ILSettingItemTypeSwitch // 开关
} ILSettingItemType;


@interface ILSettingItem : NSObject
@property (nonatomic, copy) NSString *icon;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, assign) ILSettingItemType type;// Cell的样式
@property (nonatomic, copy) void (^operation)() ; // 点击cell后要执行的操作


+ (id)itemWithIcon:(NSString *)icon title:(NSString *)title type:(ILSettingItemType)type;
@end


而ILSettingItem.m文件如下所示

#import "ILSettingItem.h"

@implementation ILSettingItem
+ (id)itemWithIcon:(NSString *)icon title:(NSString *)title type:(ILSettingItemType)type
{
    ILSettingItem *item = [[self alloc] init];
    item.icon = icon;
    item.title = title;
    item.type = type;
    return item;
}
@end


从前面的代码@property (nonatomic, copy) void (^operation)() ; 中可知,在copy形式下的代码块是存放在堆里面的,只有当ILSettingItem 对象销毁的时候,block才会销毁。此时如果代码块中引用了外部的对象,如下面这段代码(该段代码是控制器ILSettingViewController的代码)中的self(ILSettingViewController)对象,会对这个对象(self)进行强引用,从而产生文章刚开始所示图中的死循环,发生内存泄漏

 // 1.1.推送和提醒
    ILSettingItem *push = [ILSettingItem itemWithIcon:@"MorePush" title:@"推送和提醒" type:ILSettingItemTypeArrow];
    push.operation = ^{
        ILPushNoticeViewController *notice = [[ILPushNoticeViewController alloc] init];
        [self.navigationController pushViewController:notice animated:YES];
    };

所以,要想上面这一段代码不产生内存泄漏,需要做以下操作:

 ILSettingItem *push = [ILSettingItem itemWithIcon:@"MorePush" title:@"推送和提醒" type:ILSettingItemTypeArrow];

_weak  ILSettingViewController *setting = self;//把self变成一个弱引用,从而避免死循环,解决内存泄漏


    push.operation = ^{
        ILPushNoticeViewController *notice = [[ILPushNoticeViewController alloc] init];
        [setting.navigationControllerpushViewController:notice animated:YES];
    };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值