上篇这个方法传入的时候已经有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
{
"-" = (
"<PSDValue: 0x6000011b45a0>",
"<PSDValue: 0x6000011b4160>",
"<PSDValue: 0x6000011b4260>",
"<PSDValue: 0x6000011b4300>",
"<PSDValue: 0x6000011b4360>",
"<PSDValue: 0x6000011b44a0>",
"<PSDValue: 0x6000011b44e0>",
"<PSDValue: 0x6000011b4600>",
"<PSDValue: 0x6000011b4680>",
"<PSDValue: 0x6000011b46e0>"
);
"invocation.event.start" = (
"<PSDValue: 0x6000011b4520>"
);
"invocation.permit" = (
"<PSDValue: 0x6000011b4500>"
);
"invocation.start" = (
"<PSDValue: 0x6000011b4020>"
);
"navigation.*" = (
"<PSDValue: 0x6000011b4540>",
"<PSDValue: 0x6000011b5680>",
"<PSDValue: 0x6000011b56e0>"
);
"navigation.error" = (
"<PSDValue: 0x6000011b4140>"
);
"navigation.start" = (
"<PSDValue: 0x6000011b4120>",
"<PSDValue: 0x6000011b43e0>"
);
"page.*" = (
"<PSDValue: 0x6000011b5640>",
"<PSDValue: 0x6000011b5720>"
);
"page.create" = (
"<PSDValue: 0x6000011b4760>"
);
"page.destroy" = (
"<PSDValue: 0x6000011b4820>"
);
"page.load.start" = (
"<PSDValue: 0x6000011b47a0>"
);
"scene.appear.after" = (
"<PSDValue: 0x6000011b42c0>",
"<PSDValue: 0x6000011b47e0>"
);
"scene.appear.before" = (
"<PSDValue: 0x6000011b4780>"
);
"scene.cached.show" = (
"<PSDValue: 0x6000011b4480>"
);
"scene.create" = (
"<PSDValue: 0x6000011b4100>",
"<PSDValue: 0x6000011b4200>",
"<PSDValue: 0x6000011b4400>"
);
"scene.destroy" = (
"<PSDValue: 0x6000011b43c0>",
"<PSDValue: 0x6000011b4800>"
);
"scene.disappear.after" = (
"<PSDValue: 0x6000011b42e0>"
);
"scene.ready" = (
"<PSDValue: 0x6000011b47c0>"
);
"scene.wk.layertreecommitcomplete" = (
"<PSDValue: 0x6000011b4460>"
);
"session.create" = (
"<PSDValue: 0x6000011b43a0>",
"<PSDValue: 0x6000011b44c0>",
"<PSDValue: 0x6000011b4720>"
);
"session.worker.jsapi.callasync" = (
"<PSDValue: 0x6000011b4440>"
);
"session.worker.load.js" = (
"<PSDValue: 0x6000011b45e0>"
);
}
(lldb) register read r14
r14 = 0x0000600001149560
(lldb) po 0x0000600001149560
{
"-" = (
"<PSDValue: 0x6000011720c0>",
"<PSDValue: 0x600001172200>",
"<PSDValue: 0x600001170420>",
"<PSDValue: 0x600001178380>",
"<PSDValue: 0x600001178360>",
"<PSDValue: 0x600001178300>",
"<PSDValue: 0x600001178680>",
"<PSDValue: 0x600001172180>",
"<PSDValue: 0x6000011653e0>"
);
"appdelgate.application.create" = (
"<PSDValue: 0x600001171f60>"
);
"invocation.event.start" = (
"<PSDValue: 0x6000011721e0>"
);
"invocation.start" = (
"<PSDValue: 0x600001149680>"
);
"monitor.log.before" = (
"<PSDValue: 0x600001171240>"
);
"navigation.start" = (
"<PSDValue: 0x600001171e60>"
);
"page.load.complete" = (
"<PSDValue: 0x600001172060>",
"<PSDValue: 0x600001165320>"
);
"page.load.domready" = (
"<PSDValue: 0x600001178540>"
);
"page.load.error" = (
"<PSDValue: 0x600001172080>"
);
"page.load.start" = (
"<PSDValue: 0x6000011787c0>",
"<PSDValue: 0x600001172040>"
);
"performance.submit.before" = (
"<PSDValue: 0x6000011720e0>"
);
"scene.appear.after" = (
"<PSDValue: 0x600001171fe0>"
);
"scene.create" = (
"<PSDValue: 0x6000011783c0>",
"<PSDValue: 0x600001172240>"
);
"scene.create.before" = (
"<PSDValue: 0x6000011722c0>",
"<PSDValue: 0x600001172300>"
);
"scene.destroy" = (
"<PSDValue: 0x600001178740>",
"<PSDValue: 0x6000011720a0>"
);
"scene.destroy.before" = (
"<PSDValue: 0x600001178420>",
"<PSDValue: 0x600001178280>",
"<PSDValue: 0x600001195800>",
"<PSDValue: 0x6000011b4660>"
);
"scene.disappear.after" = (
"<PSDValue: 0x600001178340>"
);
"scene.loadRequest.first" = (
"<PSDValue: 0x600001172000>"
);
"scene.loadRequest.first.start" = (
"<PSDValue: 0x600001172020>"
);
"scene.ready" = (
"<PSDValue: 0x600001178720>"
);
"service.browser.restartTrueAppId" = (
"<PSDValue: 0x600001171f80>"
);
"service.rpc.finished" = (
"<PSDValue: 0x600001178660>",
"<PSDValue: 0x600001178640>"
);
"session.create" = (
"<PSDValue: 0x600001171fa0>",
"<PSDValue: 0x600001165360>",
"<PSDValue: 0x600001195940>",
"<PSDValue: 0x6000011b4640>"
);
"session.resume" = (
"<PSDValue: 0x600001165380>"
);
"view.inject.js" = (
"<PSDValue: 0x600001178520>"
);
"view.reload.fail" = (
"<PSDValue: 0x6000011787a0>"
);
"view.show.panel" = (
"<PSDValue: 0x600001178780>"
);
}
(lldb) register read r14
r14 = 0x00006000011496c0
(lldb) po 0x00006000011496c0
{
"invocation.invoke" = (
"<PSDValue: 0x6000011786a0>"
);
"invocation.invoke.before" = (
"<PSDValue: 0x6000011786c0>"
);
"view.config" = (
"<PSDValue: 0x600001178760>"
);
}
(lldb) register read r14
r14 = 0x00006000011b2b40
(lldb) po 0x00006000011b2b40
{
"*.*" = (
"<PSDValue: 0x6000011b4ca0>"
);
"-" = (
"<PSDValue: 0x6000011b4bc0>",
"<PSDValue: 0x6000011b4c60>",
"<PSDValue: 0x6000011b33a0>",
"<PSDValue: 0x6000011b3900>",
"<PSDValue: 0x6000011b3240>",
"<PSDValue: 0x6000011b31a0>",
"<PSDValue: 0x6000011b33e0>",
"<PSDValue: 0x6000011b2d60>",
"<PSDValue: 0x6000011b3540>",
"<PSDValue: 0x6000011b3680>",
"<PSDValue: 0x6000011b3b40>",
"<PSDValue: 0x6000011b3960>",
"<PSDValue: 0x6000011b38c0>",
"<PSDValue: 0x6000011b38e0>",
"<PSDValue: 0x6000011b2dc0>",
"<PSDValue: 0x6000011b39e0>",
"<PSDValue: 0x6000011b1a40>",
"<PSDValue: 0x6000011b2da0>",
"<PSDValue: 0x6000011b2d20>",
"<PSDValue: 0x6000011b3e20>",
"<PSDValue: 0x6000011b36c0>",
"<PSDValue: 0x6000011b3e00>",
"<PSDValue: 0x6000011b3da0>",
"<PSDValue: 0x6000011b3fe0>",
"<PSDValue: 0x6000011b3b20>",
"<PSDValue: 0x6000011b3d20>",
"<PSDValue: 0x6000011b4920>",
"<PSDValue: 0x6000011b4cc0>",
"<PSDValue: 0x6000011b4de0>",
"<PSDValue: 0x6000011b50e0>",
"<PSDValue: 0x6000011b5260>",
"<PSDValue: 0x6000011b5380>"
);
"application.pause" = (
"<PSDValue: 0x6000011b3620>",
"<PSDValue: 0x6000011b5120>",
"<PSDValue: 0x6000011b5300>"
);
"application.resume" = (
"<PSDValue: 0x6000011b3f00>",
"<PSDValue: 0x6000011b4e40>",
"<PSDValue: 0x6000011b5180>",
"<PSDValue: 0x6000011b4ec0>"
);
"invocation.complete" = (
"<PSDValue: 0x6000011b4f20>",
"<PSDValue: 0x6000011b5020>"
);
"invocation.error" = (
"<PSDValue: 0x6000011b3700>",
"<PSDValue: 0x6000011b5000>"
);
"invocation.event.start" = (
"<PSDValue: 0x6000011b4c00>"
);
"invocation.invoke" = (
"<PSDValue: 0x6000011b4c20>",
"<PSDValue: 0x6000011b4f00>"
);
"invocation.start" = (
"<PSDValue: 0x6000011b2b20>",
"<PSDValue: 0x6000011b5240>"
);
"navigation.*" = (
"<PSDValue: 0x6000011b5540>"
);
"navigation.start" = (
"<PSDValue: 0x6000011b2cc0>"
);
"page.*" = (
"<PSDValue: 0x6000011b5580>"
);
"page.destroy" = (
"<PSDValue: 0x6000011b3520>",
"<PSDValue: 0x6000011b3c60>",
"<PSDValue: 0x6000011b4fa0>",
"<PSDValue: 0x6000011b5140>",
"<PSDValue: 0x6000011b5340>"
);
"page.load.complete" = (
"<PSDValue: 0x6000011b2e00>",
"<PSDValue: 0x6000011b2f00>",
"<PSDValue: 0x6000011b2ce0>",
"<PSDValue: 0x6000011b3ac0>",
"<PSDValue: 0x6000011b3f40>",
"<PSDValue: 0x6000011b50a0>"
);
"page.load.error" = (
"<PSDValue: 0x6000011b3a00>",
"<PSDValue: 0x6000011b2e40>",
"<PSDValue: 0x6000011b3b00>",
"<PSDValue: 0x6000011b2d00>",
"<PSDValue: 0x6000011b50c0>"
);
"page.load.start" = (
"<PSDValue: 0x6000011b3200>",
"<PSDValue: 0x6000011b30c0>",
"<PSDValue: 0x6000011b3a20>",
"<PSDValue: 0x6000011b4d00>",
"<PSDValue: 0x6000011b4ee0>",
"<PSDValue: 0x6000011b5080>"
);
"performance.jsError" = (
"<PSDValue: 0x6000011b4f40>"
);
"performance.submit.before" = (
"<PSDValue: 0x6000011b3980>",
"<PSDValue: 0x6000011b4d20>",
"<PSDValue: 0x6000011b4f60>"
);
"proxy.request.start.handle" = (
"<PSDValue: 0x6000011b4c40>"
);
"scene.ContentView.Fallback" = (
"<PSDValue: 0x6000011b2e80>"
);
"scene.NavigationBar.ChangeColor" = (
"<PSDValue: 0x6000011b4ba0>",
"<PSDValue: 0x6000011b3840>",
"<PSDValue: 0x6000011b34c0>",
"<PSDValue: 0x6000011b3860>",
"<PSDValue: 0x6000011b3000>"
);
"scene.appear.after" = (
"<PSDValue: 0x6000011b3aa0>",
"<PSDValue: 0x6000011b3d00>",
"<PSDValue: 0x6000011b4ea0>",
"<PSDValue: 0x6000011b5060>",
"<PSDValue: 0x6000011b5360>"
);
"scene.appear.before" = (
"<PSDValue: 0x6000011b3440>",
"<PSDValue: 0x6000011b3f60>",
"<PSDValue: 0x6000011b3ca0>",
"<PSDValue: 0x6000011b5160>",
"<PSDValue: 0x6000011b4fc0>"
);
"scene.barButtonTheme.set" = (
"<PSDValue: 0x6000011b3500>"
);
"scene.component.fullScreen" = (
"<PSDValue: 0x6000011b48e0>"
);
"scene.create" = (
"<PSDValue: 0x6000011b3420>",
"<PSDValue: 0x6000011b3880>"
);
"scene.destroy" = (
"<PSDValue: 0x6000011b36e0>",
"<PSDValue: 0x6000011b3cc0>"
);
"scene.destroy.before" = (
"<PSDValue: 0x6000011b3f80>"
);
"scene.disappear.after" = (
"<PSDValue: 0x6000011b3460>",
"<PSDValue: 0x6000011b35e0>",
"<PSDValue: 0x6000011b52c0>"
);
"scene.disappear.before" = (
"<PSDValue: 0x6000011b36a0>",
"<PSDValue: 0x6000011b3720>",
"<PSDValue: 0x6000011b3ec0>",
"<PSDValue: 0x6000011b5100>",
"<PSDValue: 0x6000011b52a0>"
);
"scene.dismiss.hide" = (
"<PSDValue: 0x6000011b5220>"
);
"scene.dismiss.show" = (
"<PSDValue: 0x6000011b5200>"
);
"scene.gesture.start.before" = (
"<PSDValue: 0x6000011b3600>"
);
"scene.layout" = (
"<PSDValue: 0x6000011b48a0>"
);
"scene.navigationItem.left.back.click" = (
"<PSDValue: 0x6000011b2e60>"
);
"scene.navigationItem.left.back.create.after" = (
"<PSDValue: 0x6000011b49a0>"
);
"scene.navigationItem.left.back.create.before" = (
"<PSDValue: 0x6000011b4960>",
"<PSDValue: 0x6000011b39c0>",
"<PSDValue: 0x6000011b19c0>"
);
"scene.navigationItem.left.close.click" = (
"<PSDValue: 0x6000011b2fa0>"
);
"scene.navigationItem.left.close.create.after" = (
"<PSDValue: 0x6000011b4a00>",
"<PSDValue: 0x6000011b3a40>"
);
"scene.navigationItem.left.close.create.before" = (
"<PSDValue: 0x6000011b49c0>",
"<PSDValue: 0x6000011b3080>",
"<PSDValue: 0x6000011b12a0>"
);
"scene.navigationItem.right.setting.change" = (
"<PSDValue: 0x6000011b4b20>",
"<PSDValue: 0x6000011b32e0>"
);
"scene.navigationItem.right.setting.click" = (
"<PSDValue: 0x6000011b3800>",
"<PSDValue: 0x6000011b3d80>"
);
"scene.navigationItem.right.setting.create.after" = (
"<PSDValue: 0x6000011b4aa0>",
"<PSDValue: 0x6000011b32c0>",
"<PSDValue: 0x6000011b1740>"
);
"scene.navigationItem.right.setting.create.before" = (
"<PSDValue: 0x6000011b4a80>",
"<PSDValue: 0x6000011b1940>"
);
"scene.navigationItem.right.subsetting.click" = (
"<PSDValue: 0x6000011b3d40>"
);
"scene.navigationItem.right.subsetting.create.after" = (
"<PSDValue: 0x6000011b4ae0>",
"<PSDValue: 0x6000011b2f40>",
"<PSDValue: 0x6000011b16e0>"
);
"scene.navigationItem.right.subsetting.create.before" = (
"<PSDValue: 0x6000011b1a00>"
);
"scene.present.hide" = (
"<PSDValue: 0x6000011b51e0>"
);
"scene.present.show" = (
"<PSDValue: 0x6000011b51c0>"
);
"scene.progressView.create.after" = (
"<PSDValue: 0x6000011b4b60>",
"<PSDValue: 0x6000011b3340>",
"<PSDValue: 0x6000011b3de0>"
);
"scene.progressView.create.before" = (
"<PSDValue: 0x6000011b4b40>",
"<PSDValue: 0x6000011b2ea0>"
);
"scene.ready" = (
"<PSDValue: 0x6000011b3280>"
);
"scene.scrollview.didscroll" = (
"<PSDValue: 0x6000011b4900>"
);
"scene.securitytipview.show" = (
"<PSDValue: 0x6000011b38a0>"
);
"scene.titleView.create.after" = (
"<PSDValue: 0x6000011b4a60>",
"<PSDValue: 0x6000011b37e0>"
);
"scene.titleView.create.before" = (
"<PSDValue: 0x6000011b4a20>",
"<PSDValue: 0x6000011b37c0>",
"<PSDValue: 0x6000011b30e0>"
);
"scene.titleView.righticon.click" = (
"<PSDValue: 0x6000011b3820>"
);
"scene.titleView.subtitle.click" = (
"<PSDValue: 0x6000011b3780>"
);
"scene.titleView.title.set" = (
"<PSDValue: 0x6000011b17e0>"
);
"view.resize" = (
"<PSDValue: 0x6000011b4840>"
);
}
可见
"scene.disappear.after" = (
"<PSDValue: 0x6000011b42e0>"
);中的PSDValue的weakObjectValue就是要找的
(lldb) po [0x6000011b4440 weakObjectValue]
<NPPlugin4Session: 0x6000011b4380>
那title的就是
"scene.titleView.title.set" = (
"<PSDValue: 0x600000466000>"
);
"view.resize" = (
"<PSDValue: 0x6000004ab600>"
);
}
(lldb) po [0x600000466000 weakObjectValue]
<NBPlugin4NavigationTitleView: 0x600000ad2760>
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;
}