iOSApp内存优化(二)

在我们的app的业务层中使用了MVVM架构,为了更好的实现MVVM,我们在CocoaPods中引入了ReactiveCocoa, 这样就会大量使用Block,很多时候Block也的确比Delegate,Target-Action使用起来要方便。顺便再推荐个第三方类库BlocksKit,但是在使用Block的时候最容易出现的问题就是循环引用,就循环引用的问题,循环引用危害非常大,controller中只要有循环引用出现,就controller就无法释放,导致app使用内存越来越大。

循环引用出现的原因

    // 播放器显示位置(竖屏时)
    self.playView.frame = CGRectMake(0, 20, SCREEN_WIDTH, SCREEN_WIDTH * 9 / 16);
    // 添加到当前控制器的view上
    [self.view addSubview:self.playView];
    // 指定一个作为播放的控制器
    self.playView.contrainerViewController = self;

这里contrainerViewController一不注意就出现了循环引用,导致controller无法释放。

细心的同学就会发现在第二句形成了循环引用的问题。然而网上所有讲到JS和OC通信的文章基本上都是这么写的,却很少有人指出这里有循环引用的问题,真是害人不浅,也怪自己粗心,不注意。

检查循环引用

根据iOS内存管理机制的基本原理:当某个对象的引用计数器为0时,它就会自动调用dealloc方法。所以在检查页面是否有循环引用的时候,只需要看controller的dealloc方法是否会被执行就可以了。当controller pop出去后,如果每调用controller的dealloc方法,说明它的某个属性对象仍然被持有,未被释放。controller页面需要加入以下方法:

- (void)dealloc {
    DLog(@"[%@ dealloc]", [self class]);
}

解决办法

@weakify(self);  
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
	@strongify(self);
	[self doSomething];
	[self doOtherThing];
});

对于@weakify@strongify这里两个宏代码的原理,回头会专门写一篇文章来介绍。

#import <Foundation/Foundation.h>
#import "WebJSExport.h"

@interface WeakWebJSExportDelegate : NSObject<WebJSExport>

@property (nonatomic, weak) id<WebJSExport> webJSExportDelegate;

- (instancetype)initWithDelegate:(id<WebJSExport>)webJSExportDelegate;

@end
#import "WeakWebJSExportDelegate.h"

@implementation WeakWebJSExportDelegate

- (instancetype)initWithDelegate:(id<WebJSExport>)webJSExportDelegate {
    self = [super init];
    if (self) {
        _webJSExportDelegate = webJSExportDelegate;
    }
    return self;
}

#pragma mark - WebJSExport
- (void)appOpenUrl:(NSString *)openJson {
    [self.webJSExportDelegate appOpenUrl:openJson];
}

然后需要将向webView注入全局对象的部分改为一下形式:

JSContext *context = [self.webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
WeakWebJSExportDelegate *weakWebJSExportDelegate = [[WeakWebJSExportDelegate alloc] initWithDelegate:self];
context[@"XXXX"] = weakWebJSExportDelegate;
context.exceptionHandler = ^(JSContext *context, JSValue *exception) {
        DLog(@"JS Error: %@", exception);
};


code
这里是修改代码的地方!

这里是修改网站内容的地方,如果你想有文章想要发表,就给我发邮件吧!.