iOS WKWebView 에서 Message Handler 메모리 누 출 문제 의 완벽 한 해결 과정

배경
프로젝트 에서 WKWebView 를 사용 하여 기 존의 UIWebView 를 교 체 했 습 니 다.Hybird 개발 과 관련 되 어 있 습 니 다.우 리 는 H5 와 상호작용 을 해 야 하기 때문에 WKWebView Configuration 의 WKUserContentController 를 사 용 했 습 니 다.
그래서 초기 화 코드 는 다음 과 같 습 니 다.

  WKUserContentController *userContentController = [[WKUserContentController alloc] init];
  [userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];
  [userContentController addScriptMessageHandler:self name:Upload_Action];

  // WKWebView   
  WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
  configuration.userContentController = userContentController;

  _webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration];
  _webView.navigationDelegate = self;
  _webView.UIDelegate = self;
GetKeyiOSAndroid_Action Upload_Action 은 각각 H5 가 message handler 방식 으로 OC 를 호출 하 는 두 가지 방법 이다.
이때 이미 위험 이 발생 했다.왜냐하면[userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];여기 서 userContentController 는 self 를 가지 고 있 습 니 다.그리고 userContentController 는 configuration 에 의 해 가지 고 있 습 니 다.최종 적 으로 webview 가 가지 고 있 습 니 다.그리고 webview 는 self 의 개인 변수 이기 때문에 self 도 self 를 가지 고 있 습 니 다.그래서 이 럴 때 순환 적 으로 인용 하 는 문제 가 존재 하여 인터페이스 가 pop 또는 dismiss 에 의 해 존재 합 니 다.풀 려 나 지 않 습 니 다.
물론 정적 인터페이스 일 뿐 이거 나 H5 와 의 상호작용 내용 이 이 페이지 의 내용 에 만 국한 된다 면 단순 한 메모리 누 출 일 뿐 이지 만 이때 H5 와 의 상호작용 방법 에 전체 변수 나 전체적인 내용 이 관련 된다 면 통제 할 수 없습니다.
이 문 제 는 우리 웹 페이지 가 token 이 만 료 되 고 로그 인 상태 가 바 뀌 었 다 는 통 지 를 감청 한 다음 에 화면 을 새로 고치 고 요청 을 다시 보 내기 때 문 입 니 다.이 일련의 동작 은 사용자 의 전체 정보 와 상호작용 을 하기 때문에 웹 페이지 를 방문 한 후에 계 정 을 바 꾸 어 로그 인 할 때 이전에 방문 한 웹 페이지 요청 이 있 는 것 을 발견 할 수 있 습 니 다.또한 token 이 token 의 만 료 오 류 를 보고 하지 않 았 기 때문에 로그 인 후 token 으로 오 작 동 하여 만 료 되 었 고 이 어 로그 인 인터페이스 로 차 였 습 니 다.
charles 스냅 백 을 통 해 이 웹 페이지 들 은 로그 인 계 정 에 접근 하지 않 은 모든 화면 을 전환 하고 있 음 을 알 수 있 습 니 다.그래서 잠 금 문제 가 있 을 때 웹 페이지 는 여전히 존재 합 니 다.로그 인 을 전환 한 후에 로그 인 상태 가 바 뀌 었 다 는 통 지 를 받 았 습 니 다.인터페이스 를 다시 갱신 하여 요청 을 보 내 고 오 류 를 되 돌려 주 었 습 니 다.더 나 아가 로그 인 후에 차 인 bug 가 발생 했 습 니 다.
해결 방안:
순환 인용 인 만큼 한쪽 의 강 한 인용 을 타파 하고 약 한 인용 으로 바 꾸 거나 인용 을 직접 제거 해 야 한다.생각 이 분명 해 졌 다.
시도 1:

id __weak weakSelf = self;
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addScriptMessageHandler:weakSelf name:GetKeyiOSAndroid_Action];
아이디어 블록 모방,결과 실패
시도 2:
viewWillDisappear/viewDidDisappear 생명주기 방법 에서 호출

[_webView.configuration.userContentController removeAllUserScripts];
이것 은 골 치 아 픈 시도 라 고 할 수 있 는데,문서 설명 을 보면 곧 알 수 있다.저절로 넘어가다

시도 3:
초기 화 할 때 ScriptMessage Handler 를 추가 하지 않 고 Notificenter/KVC 와 같은 생각 입 니 다.

- (void)viewWillAppear:(BOOL)animated {
 [super viewWillAppear:animated];

 [_webView.configuration.userContentController addScriptMessageHandler:self name:GetKeyiOSAndroid_Action];
 [_webView.configuration.userContentController addScriptMessageHandler:self name:Upload_Action];
}

- (void)viewWillDisappear:(BOOL)animated {
 [super viewWillDisappear:animated];

 [_webView.configuration.userContentController removeScriptMessageHandlerForName:GetKeyiOSAndroid_Action];
 [_webView.configuration.userContentController removeScriptMessageHandlerForName:Upload_Action];
}
결과 성공
소결:
이전에 WKWebView 를 사 용 했 을 때 많은 블 로그 의 내용 은 Message Handler 를 어떻게 추가 하 는 지 말 했 을 뿐 이 메모리 가 누 출 될 위험 이 있 는 것 은 아니 었 습 니 다.만약 에 페이지 안의 데이터 호출 만 한다 면 이 문 제 를 전혀 발견 하지 못 할 것 입 니 다.
이 구 덩이 는 이미 메 웠 다!
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 참고 학습 가치 가 있 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기