上篇这个方法传入的时候已经有maintitle值了-[H5NavigationTitleView setMainTitle:subtitle:]
然后看下它的上个方法
-[NBPlugin4NavigationTitleView handleEvent:]
r14 = [@"scene.titleView.title.set" isEqualToString:rdx];
[rbx release];
if (r14 != 0x0) {
r13 = [[r13 navigationTitleView] retain];
r14 = [[r12 mainTitle] retain];
rbx = [[r12 subtitle] retain];
[r13 setMainTitle:r14 subtitle:rbx];
[rbx release];
[r14 release];
[r13 release];
r13 = r12;
}
可以看到 mainTitle 取的是[r12 mainTitle]。
r12是-[NBPlugin4NavigationTitleView handleEvent:]传入的变量,是 NBNavigationTitleViewEvent类型
并且mainTitle有值。
还有执行顺序
NBNavigationTitleViewEvent-scene.titleView.create.before
NBNavigationTitleViewEvent-scene.titleView.title.set
PSDPageEvent-page.load.start
PSDPageEvent-page.load.complete
NBNavigationTitleViewEvent-scene.titleView.title.set
然后看上一个方法如何创建NBNavigationTitleViewEvent的
MPH5Demo_pod`-[PSDKernel handleEvent:evenListenersDict:]:
下断点 打印r14
(lldb) register read r14
r14 = 0x00006000011b4000
(lldb) po 0x00006000011b4000
{
"-" = (
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
);
"invocation.event.start" = (
""
);
"invocation.permit" = (
""
);
"invocation.start" = (
""
);
"navigation.*" = (
"",
"",
""
);
"navigation.error" = (
""
);
"navigation.start" = (
"",
""
);
"page.*" = (
"",
""
);
"page.create" = (
""
);
"page.destroy" = (
""
);
"page.load.start" = (
""
);
"scene.appear.after" = (
"",
""
);
"scene.appear.before" = (
""
);
"scene.cached.show" = (
""
);
"scene.create" = (
"",
"",
""
);
"scene.destroy" = (
"",
""
);
"scene.disappear.after" = (
""
);
"scene.ready" = (
""
);
"scene.wk.layertreecommitcomplete" = (
""
);
"session.create" = (
"",
"",
""
);
"session.worker.jsapi.callasync" = (
""
);
"session.worker.load.js" = (
""
);
}
(lldb) register read r14
r14 = 0x0000600001149560
(lldb) po 0x0000600001149560
{
"-" = (
"",
"",
"",
"",
"",
"",
"",
"",
""
);
"appdelgate.application.create" = (
""
);
"invocation.event.start" = (
""
);
"invocation.start" = (
""
);
"monitor.log.before" = (
""
);
"navigation.start" = (
""
);
"page.load.complete" = (
"",
""
);
"page.load.domready" = (
""
);
"page.load.error" = (
""
);
"page.load.start" = (
"",
""
);
"performance.submit.before" = (
""
);
"scene.appear.after" = (
""
);
"scene.create" = (
"",
""
);
"scene.create.before" = (
"",
""
);
"scene.destroy" = (
"",
""
);
"scene.destroy.before" = (
"",
"",
"",
""
);
"scene.disappear.after" = (
""
);
"scene.loadRequest.first" = (
""
);
"scene.loadRequest.first.start" = (
""
);
"scene.ready" = (
""
);
"service.browser.restartTrueAppId" = (
""
);
"service.rpc.finished" = (
"",
""
);
"session.create" = (
"",
"",
"",
""
);
"session.resume" = (
""
);
"view.inject.js" = (
""
);
"view.reload.fail" = (
""
);
"view.show.panel" = (
""
);
}
(lldb) register read r14
r14 = 0x00006000011496c0
(lldb) po 0x00006000011496c0
{
"invocation.invoke" = (
""
);
"invocation.invoke.before" = (
""
);
"view.config" = (
""
);
}
(lldb) register read r14
r14 = 0x00006000011b2b40
(lldb) po 0x00006000011b2b40
{
"*.*" = (
""
);
"-" = (
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
);
"application.pause" = (
"",
"",
""
);
"application.resume" = (
"",
"",
"",
""
);
"invocation.complete" = (
"",
""
);
"invocation.error" = (
"",
""
);
"invocation.event.start" = (
""
);
"invocation.invoke" = (
"",
""
);
"invocation.start" = (
"",
""
);
"navigation.*" = (
""
);
"navigation.start" = (
""
);
"page.*" = (
""
);
"page.destroy" = (
"",
"",
"",
"",
""
);
"page.load.complete" = (
"",
"",
"",
"",
"",
""
);
"page.load.error" = (
"",
"",
"",
"",
""
);
"page.load.start" = (
"",
"",
"",
"",
"",
""
);
"performance.jsError" = (
""
);
"performance.submit.before" = (
"",
"",
""
);
"proxy.request.start.handle" = (
""
);
"scene.ContentView.Fallback" = (
""
);
"scene.NavigationBar.ChangeColor" = (
"",
"",
"",
"",
""
);
"scene.appear.after" = (
"",
"",
"",
"",
""
);
"scene.appear.before" = (
"",
"",
"",
"",
""
);
"scene.barButtonTheme.set" = (
""
);
"scene.component.fullScreen" = (
""
);
"scene.create" = (
"",
""
);
"scene.destroy" = (
"",
""
);
"scene.destroy.before" = (
""
);
"scene.disappear.after" = (
"",
"",
""
);
"scene.disappear.before" = (
"",
"",
"",
"",
""
);
"scene.dismiss.hide" = (
""
);
"scene.dismiss.show" = (
""
);
"scene.gesture.start.before" = (
""
);
"scene.layout" = (
""
);
"scene.navigationItem.left.back.click" = (
""
);
"scene.navigationItem.left.back.create.after" = (
""
);
"scene.navigationItem.left.back.create.before" = (
"",
"",
""
);
"scene.navigationItem.left.close.click" = (
""
);
"scene.navigationItem.left.close.create.after" = (
"",
""
);
"scene.navigationItem.left.close.create.before" = (
"",
"",
""
);
"scene.navigationItem.right.setting.change" = (
"",
""
);
"scene.navigationItem.right.setting.click" = (
"",
""
);
"scene.navigationItem.right.setting.create.after" = (
"",
"",
""
);
"scene.navigationItem.right.setting.create.before" = (
"",
""
);
"scene.navigationItem.right.subsetting.click" = (
""
);
"scene.navigationItem.right.subsetting.create.after" = (
"",
"",
""
);
"scene.navigationItem.right.subsetting.create.before" = (
""
);
"scene.present.hide" = (
""
);
"scene.present.show" = (
""
);
"scene.progressView.create.after" = (
"",
"",
""
);
"scene.progressView.create.before" = (
"",
""
);
"scene.ready" = (
""
);
"scene.scrollview.didscroll" = (
""
);
"scene.securitytipview.show" = (
""
);
"scene.titleView.create.after" = (
"",
""
);
"scene.titleView.create.before" = (
"",
"",
""
);
"scene.titleView.righticon.click" = (
""
);
"scene.titleView.subtitle.click" = (
""
);
"scene.titleView.title.set" = (
""
);
"view.resize" = (
""
);
}
可见
"scene.disappear.after" = (
""
);中的PSDValue的weakObjectValue就是要找的
(lldb) po [0x6000011b4440 weakObjectValue]
那title的就是
"scene.titleView.title.set" = (
""
);
"view.resize" = (
""
);
}
(lldb) po [0x600000466000 weakObjectValue]
weakObjectValue的值是类的实例,参数(NBNavigationTitleViewEvent)呢?
就是- (void)handleEvent:(id)arg1 evenListenersDictS:(id)arg2;的arg1
那继续arg1是-[PSDKernel handleCaptureEvent:]中调用【handleEvent:(id)arg1 evenListenersDictS】传过来的
-[PSDKernel handleCaptureEvent:]的参数是
-[PSDKernel dispatchEvent:]调用[PSDKernel handleCaptureEvent:传过来的,就是arg1
然后下一层是fireEvent直接调用
-[PSDKernel fireEvent:]{
r14 = self;
rsi = @selector(handleCaptureEvent:);
_objc_msgSend(r14, rsi);
}
再下一层
-[PSDKernel dispatchEvent:]断点停在了第二个setEventPhase上面的地方
层层查找 参数r12是
r12 = [arg2 retain];
var_E0 = r12;
r12 = var_E0;
[r12 setEventPhase:0x0];
rbx = [[PSDContext contextWithEvent:r12 eventTargetList:r14] retain];
[r12 setContext:rbx];
结果r12就是dispatchEvent的参数
dispatchEvent这个hook会出错,可能是继承的问题。
查看下一个-[NBViewControllerProxy dispatchEvent:]
它是
rbx = [[self psdScene] retain];
r14 = [rbx dispatchEvent:r12];
调用的self psdScene 然后dispatchEvent:
打印一下
arg1上个方法就有值了,
在void -[NBViewControllerProxy sendSetMainTitleEvent:subtitle:]中
调用的rbx = [[NBNavigationTitleViewEvent setTitleEvent:r12 subtitle:arg3] retain];
[self dispatchEvent:rbx];
这个也是上个方法已有值
void ___33-[NBViewControllerProxy updateUI]_block_invoke(int arg0, int arg1, int arg2) {
r13 = arg0;
r15 = [arg1 retain];
if (arg2 == 0x0) {
rbx = [[r15 description] retain];
r14 = [rbx length];
[rbx release];
if (r14 != 0x0) {
var_40 = objc_loadWeakRetained(r13 + 0x20);
rbx = [[r15 description] retain];
rax = objc_loadWeakRetained(r13 + 0x20);
r12 = [[rax options] retain];
r14 = [[r12 defaultSubtitle] retain];
[var_40 sendSetMainTitleEvent:rbx subtitle:r14];
[r14 release];
[r12 release];
[rax release];
[rbx release];
[var_40 release];
}
}
[r15 release];
return;
}
r15 = [arg1 retain];
rbx = [[r15 description] retain];
这里边应该是[rax evaluateJavaScript:@"document.title" completionHandler:&var_50];的block里面的。
至此全流程结束
下边应该总结一个线路图
但会不会出错呢?
目前用的uiwebview但evaluateJavaScript是wk的方法啊,
当然没错,因为给uiwebview增加了这个方法
void -[UIWebView evaluateJavaScript:completionHandler:](void * self, void * _cmd, void * arg2, void * arg3) {
r13 = self;
r14 = [arg2 retain];
r12 = [arg3 retain];
rdx = @"document.location.href";
if ([r14 isEqualToString:rdx] == 0x0) goto loc_100701476;
loc_1007013fc:
var_-72 = r13;
rbx = [[r13 URL] retain];
r13 = [[rbx absoluteString] retain];
[rbx release];
rax = [r13 length];
if ((r12 == 0x0) || (rax == 0x0)) goto loc_100701469;
loc_100701457:
(*(r12 + 0x10))(r12, r13, 0x0);
rdi = r13;
goto loc_1007014c1;
loc_1007014c1:
[rdi release];
goto loc_1007014c7;
loc_1007014c7:
[r12 release];
[r14 release];
if (*___stack_chk_guard != *___stack_chk_guard) {
__stack_chk_fail();
}
return;
loc_100701469:
[r13 release];
r13 = var_-72;
goto loc_100701476;
loc_100701476:
if ([NSThread isMainThread] == 0x0) goto loc_1007014fb;
loc_10070148e:
rbx = [[r13 stringByEvaluatingJavaScriptFromString:r14] retain];
if (r12 != 0x0) {
(*(r12 + 0x10))(r12, rbx, 0x0);
}
rdi = rbx;
goto loc_1007014c1;
loc_1007014fb:
if ([r14 length] != 0x0) {
if (r12 != 0x0) {
var_-64 = r14;
var_-96 = intrinsic_movdqa(var_-96, intrinsic_punpcklqdq(zero_extend_64(@"js"), zero_extend_64(@"callback")));
r15 = r13;
r13 = [r12 copy];
*(&var_-64 + 0x8) = r13;
rbx = [[NSDictionary dictionaryWithObjects:rdx forKeys:&var_-96 count:0x2] retain];
[r15 performSelectorOnMainThread:@selector(nbEvaluateJavaScriptWithParams:) withObject:rbx waitUntilDone:0x0];
[rbx release];
[r13 release];
}
else {
[r13 performSelectorOnMainThread:@selector(stringByEvaluatingJavaScriptFromString:) withObject:r14 waitUntilDone:0x0];
}
}
goto loc_1007014c7;
}
作者:_小呵呵