国庆小集团队休息了两周,现在我们又回来了。整装待发,后面我们努力为大家带来更多更好的文章。
上周公众号发布的以下文章:
本期知识小集的主要内容包括:
- 利用 GCD 信号量将异步方法改造为同步方法
- 提高开发效率 --- UI 部分
- WKWebView 使用 WKWebViewJavascriptBridge 需要注意的地方
- 开源库使用的 Clang __attributes__
利用 GCD 信号量将异步方法改造为同步方法
作者 : halohily
有的时候,我们会遇到一个同步方法(该方法的所有工作在返回之前已全部完成)的内部实现,需要依赖其他异步过程的情况。比如接口定义了一个开启聊天会话的方法,返回值为布尔值。从返回值类型不难推测,我们希望这个方法返回之时,会话是否开启成功就已经确切得知。然而,开启会话的内部实现仅仅是向服务端发起连接请求,是否连接成功需要等待服务端的响应,显然这是一个异步的过程。这就是一个常见的异步过程需要改造为同步(对外表现同步)的场景。如何实现呢?可以采用 GCD 的信号量:发起连接请求之前,创建一个初始值为 0 的信号量,在方法返回之前请求该信号量(P 操作),同时,在连接请求的结果回调中释放该信号量(V 操作)。这样,发起连接请求后,由于信号量初始值为 0,会阻塞在请求信号量的地方,连接请求回调回来之后,释放信号量,刚刚的信号量请求被满足,方法得以返回。这样对外表现即为一个同步且耗时的开启会话操作,虽然这个场景比较别扭,但与此类似的情景是很常见的。
在大家熟知的 AFNetworking 中,就有这样的应用:
提高开发效率 --- UI 部分
作者 : Lefe_x
最近在探索可以提高开发效率的方法,目前先从 UI 方面入手,旨在能够快速的创建 UI,避免做不断重复的工作,现初步找到几种方法并开始实践,希望对你能够有启发,如果你有更好的想法,欢迎分享给我:
- 使用文件模板 :对于某些重复性比较大的 ViewController,可以通过定义模板,这样创建 ViewController 的时候直接使用模板创建,会节省一部分时间;如果有一套自己创建 UI 的命名规则,还会节省一部分时间,模板代码越多,就越少写多余的代码;
- 使用代码片段 :对于一些小功能,比如创建某个 Label,某个属性;如果定义成代码片段,也会节约一部分时间;有了代码片段,那么写代码就是成段成段的写,这里需要注意定义代码片段时命名规则,避免由于忘记代码片段的名字浪费查找的时间;
- 积累自己的UI库 :其实很多 UI 在其它项目中已经写过了,如果平时注重积累,那么很多 UI 直接搬过来既可以使用,这里写 UI 时要记得解耦,UI 部分尽量不要与项目耦合,这样复用性更强;
-
统一管理 UIColor
:一个 APP 中常用的颜色就那么几种,这些颜色使用 Color set 统一管理,优点就是你不需要不断地看某个字体的颜色是什么,某个 view 的背景颜色是什么,直接调用已经创建的颜色即可,比如:
+ (UIColor *)lef_blackColor;
- 使用Sketch :你往往会抱怨 UI 切的图,标记的位置并不是你想要的,反复的和 UI 要切图,要颜色,如果使用好 Sketch 这个工具,很多图你自己都可以搞定,不过有的 UI 使用的是 PS 那就尴尬了;
- 系统学习 UI 知识 :当你花了好大力气实现某个 UI 效果后,发现系统提供了一个 API,一句话就实现了,心里一万个草泥马,你所谓遇到的坑,往往就是没有系统地学习 UI 的原理,导致遇到莫名其妙的问题不知如何下手。
WKWebView 使用 WKWebViewJavascriptBridge 需要注意的地方
原生端与 H5 端交互,比较常用的就是 WebViewJavascriptBridge。建桥过程这边不再赘述,只要下载 Github 上的 Demo 参考即可,OGitHub - marcuswestin/WebViewJavascriptBri...。
注意点一:Run 以后会捕捉到一个 Crash,在官网的 Demo 里同样会有这个 Crash,如图一。这个 Crash 只有在用 WKWebView 里会出现,用 UIWebView 是好的。
解决方法:在
WKWebViewJavascriptBridge.m
文件line 150 后面加一行代码。如图二。参考 issue :
github.com/marcuswesti…
。不知为何,作者没有合并该 issue,源码里也未修复。因此用 cocoapods 集成库的同学,每次 pod install 后要检查源码中是否有添加上述一行代码。
注意点二:注册 bridge 后,与 H5 的交互无法成功。
解决方法:检查一下 H5 小伙伴代码里有没有图三代码段落。这一段 js 代码是不能改的,需原样复制。查看源码发现,在
WKWebViewJavascriptBridge.m
文件 line 135 方法中,
[_base injectJavascriptFile]
是注入 js 文件,也是交互的关键。在执行这行代码之前,有
[_base isBridgeLoadedURL:url]
这个判断,点进去查看该判断的实现,发现两个宏
kCustomProtocolScheme
和
kBridgeLoaded
,分别对应
@"wvjbscheme"
和
@"__BRIDGE_LOADED__"
。 这也就跟图三代码中的
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
对上了。