美文网首页
iOS 一个由全局弹框引发的内存思考

iOS 一个由全局弹框引发的内存思考

作者: 左左4143 | 来源:发表于2018-08-15 23:49 被阅读138次

现在一般的App都有很多底部弹出框,比如下面这样的


image





或者这样的



image



上面两个截图中的控件是我在工程中使用频率较高的两个自定义控件,一个用来展示多选框的sheetView,一个用来展示分享面板的shareView,都是可以全局使用的

sheetView使用方法为

NSArray *passports = @[@"无",@"有",@"过期"];
ZGQActionSheetView *sheetView = [[ZGQActionSheetView alloc] initWithOptions:passports Completion:^(ZGQActionSheetView *sheetView, NSInteger index) {
    //doSomething
} cancel:^{ 
        
}];
[sheetView show];

其实是将一个tableView放到了[UIApplication sharedApplication].keyWindow上,在init方法里实现

由外部调用,每次都可以传入不同的数组,来改变选项的内容

shareView是自定义的分享面板,底层封装了友盟的分享模块,起初是创建了一个shareManager 来统一管理所有页面的分享动作

+ (instancetype) manager {
    static ZCQShareManager *manager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        manager = [[ZCQShareManager alloc] init];
    });
    return manager;
}

shareManager持有shareView 并在单例初始化时将shareView add 到[UIApplication sharedApplication].keyWindow

分享操作是这样

ZCQShareUrlModel *model = [[ZCQShareUrlModel alloc]initWithTitle:shareName description:shareDescription image:shareLogoUrl];
model.shareUrl = shareUrl;
    
[[ZCQShareManager manager] openShareViewWithModel:model completion:^(ZCQShareType type) {
    //分享回调
    
} result:^(NSError *error, ZCQShareType type) {
    //分享结果回调
    
} cancelBlock:^{
    //取消分享回调
    
}];

起初分享面板默认展示的是所有的分享渠道,后来接到产品的需求,要求某些页面自定义分享渠道(比如某些页面不允许分享到App内部的消息),但是shareManager是一个单例,分享面板被单例持有,我如果修改了面板上的UI(比如去掉了消息按钮),所有的地方调用都会没有,这时候我就想到能不能像想sheetView一样,每次都生成一个新对象,不用单例,于是我为了方便(不修改调用的方法)将代码改成了这样

+ (instancetype) manager {
    ZCQShareManager *manager = [[ZCQShareManager alloc] init];;
    return manager;
}

我以为每次生成一个新的对象,不就可以每次在调用之前自定义都分享给哪几个渠道了?

但是我将代码修改之后分享面板却怎么也调不出来了

其实这里就犯了一个错误,因为对内存管理还是不理解,sheetView 之所以可以每次生成一个新对象并调出来是因为它生成后是直接添加到keyWindow上的,由于keyWindow是全局存在的 所以keyWindow持有了sheetVie 它就能显示出来。

shareView 虽然是添加到了keyWindow上,但他是被shareManager持有的,shareManager如果是一个单例的话,没有问题,但如果它不是一个单例而是变成了一个局部变量,在调用[ZCQShareManager manager]的地方 这个对象一旦了作用域就销毁了,shareManager销毁了,那么它持有的shareView也自然就没了,就无法调出来

当然解决的办法很简单,就是直接让keyWindow持有shareView,不再通过shareManager去持有它,不过这样改动的代码就比较多了。

相关文章

网友评论

      本文标题:iOS 一个由全局弹框引发的内存思考

      本文链接:https://www.haomeiwen.com/subject/srblixtx.html