转载

内存泄露

原文

  • 在检查项目内存泄露的时候遇到的一个问题记录下:

    在webViewController里打开一个新的webViewController的时候报了内存泄露,代码如下:

-(void)registPushByWeb {
  [_bridge registerHandler:@"openPage" handler:^(id data, WVJBResponseCallback responseCallback) {
      NSString *url = [data objectForKey:@"data"];
      NSInteger type = [[data objectForKey:@"type"] integerValue];
      if (type == 1) {
          NSString *fullpath = [NSString stringWithFormat:@"%@?type=%ld", url, (long)type];
          [KZWRouterHelper pushbyURL:fullpath navgtionBarHidden:NO navigationTitle:nil isNeedBack:NO];
      }
  }];
}

代码的意思利用jsbridge注册一个openPage方法打开一个webViewController,其实就是在打开一个自己因为自己就是webViewController,可能有点绕,意思就是这个意思。

看了半天也觉得没问题啊,然后看了下页面的代码,发现如下:

-(void)registRenewalSuccess {
  [_bridge registerHandler:@"renewalSuccess" handler:^(id data, WVJBResponseCallback responseCallback) {
      [self.navigationController popToRootViewControllerAnimated:YES];
      responseCallback(@"success");
  }];
}

发现问题了,self,然后我改成如下:

-(void)registRenewalSuccess {
   @WeakObj(self);
  [_bridge registerHandler:@"renewalSuccess" handler:^(id data, WVJBResponseCallback responseCallback) {
       @StrongObj(self);
      [self.navigationController popToRootViewControllerAnimated:YES];
      responseCallback(@"success");
  }];
}
  • 问题是解决了,但是报了一个错“invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.

libc++abi.dylib: terminate_handler unexpectedly threw an exception”开始一脸懵逼啊。这什么情况,不加weakself就没问题。

正常流程走,我去搜了下这个错,但是并没有解决我的问题啊,什么可变数组add问题,还是一脸懵逼啊。后来灵感来了想到了这里:

[self.webView addObserver:self
                 forKeyPath:NSStringFromSelector(@selector(estimatedProgress))
                    options:0
                    context:nil];
[self.webView addObserver:self 
             forKeyPath:NSStringFromSelector(@selector(title)) 
                options:NSKeyValueObservingOptionNew context:NULL];

这里不就是add嘛,然后看这里:

-(void)dealloc {
  self.webView.UIDelegate = nil;
  [self.webView stopLoading];
  [self.webView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
}

很清晰的title的观察没有清,改成如下:

-(void)dealloc {
  self.webView.UIDelegate = nil;
  [self.webView stopLoading];
  [self.webView removeObserver:self forKeyPath:NSStringFromSelector(@selector(estimatedProgress))];
  [self.webView removeObserver:self forKeyPath:NSStringFromSelector(@selector(title))];
}

好了,反思,在内存这块要比较关注Observer这个东西,然后就是block还是要时刻记得weakself和一些常见的内存泄露坑。

正文到此结束
Loading...