情景:某一頁面有一UIWebView,點擊webView上返回按鈕退回原界面。打斷點發(fā)現(xiàn)沒有走dealloc方法。
代碼:
- 1、在VC.h里引入JS框架<JavaScriptCore/JavaScriptCore.h>,并聲明JSObjectProtocol協(xié)議。方便JS調(diào)用OC方法。
#import "BaseViewController.h"
#import <JavaScriptCore/JavaScriptCore.h>
@protocol JSObjectProtocol <JSExport>
/**
JS調(diào)用OC實現(xiàn)退出當前頁面
*/
- (void)CloseView;
@end
- 2、該VC遵循<UIWebViewDelegate、JSObjectProtocol>協(xié)議。
@interface InviteViewController : BaseViewController<UIWebViewDelegate、JSObjectProtocol>
@property (nonatomic,strong)UIWebView *webView;
@end
- 3、搭建界面,并設(shè)置webView的代理為self
_webView = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, kDeviceWidth, kDeviceHeight-kNavigationBar-20)];
_webView.backgroundColor=[UIColor lightGrayColor];
_webView.mediaPlaybackRequiresUserAction = NO;
_webView.delegate = self;
[self.view addSubview:_webView];
- 4、在webView代理方法里設(shè)置JSContext對象
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
JSContext *context = [webView valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"anxinjiaohu"] = self;
context[@"anxinactivity"] = self;
}
- 5、實現(xiàn)JS協(xié)議方法
- (void)CloseView {
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self closeThisController];
}];
}
- (void)closeThisController {
if (self.isFromActivityPage == YES) {
UIViewController *rootVC = self.presentingViewController;
while (rootVC.presentingViewController) {
rootVC = rootVC.presentingViewController;
}
[rootVC dismissViewControllerAnimated:YES completion:nil];
} else {
[self.navigationController popViewControllerAnimated:YES];
}
NSLog(@"該退出了");
}
接下來運行程序會發(fā)現(xiàn),dealloc方法沒被調(diào)用,如果網(wǎng)頁自動播放聲音,退回去之后,聲音還在不停的播放。明顯對象沒有釋放,存在內(nèi)存泄漏。那是什么導致的呢?
經(jīng)排查,原因出在下面兩句代碼上
context[@"anxinjiaohu"] = self;
context[@"anxinactivity"] = self;
在這里,self被強引用了。小編又嘗試使用__weak,結(jié)果發(fā)現(xiàn)問題還是解決不了。最后怎么解決的呢?
這里,我們需要找到context對應(yīng)的控制器,然后用單例方法來替代self,即可完美解決這個問題。
將上述代碼修改為:
context[@"anxinjiaohu"] = [InviteViewController sharedInstance];
context[@"anxinactivity"] = [InviteViewController sharedInstance];
用模擬器再次運行程序,發(fā)現(xiàn)調(diào)用dealloc了,證明對象銷毀了。但是,發(fā)現(xiàn)銷毀對象之后,xcode仍在不停的打印一些信息。

xcode打印的東西.png
但是用手機運行的話,則不會打印。這其實是xcode配置的問題,xcode7就不會存在。解決方法很簡單:
- xcode打開"Product"——"Scheme"——"Edit Scheme";
- 選擇"Arguments",在Environment Variables中添加"OS_ACTIVITY_MODE:disable"即可。
如下圖所示:

xcode配置.png