详解mpaas离线包pushWindow方法的两个参数defaultTitle和readTitle在iOS客户端代码执行流程以及自定义导航条之后的适配方法(三)

Antonia ·
更新时间:2024-09-21
· 750 次阅读

上篇这个方法传入的时候已经有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; }
作者:_小呵呵



导航条 自定义 IOS

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章