@@ -198,6 +198,123 @@ git push origin HEAD:refs/for/Dev0.0.1
198198
199199让调试变的欢乐起来吧!
200200
201+ SourceTree 搭配 Kaleidoscope 进行 Code Review
202+ ----
203+
204+ 平时在 ` Gitlab ` 、` GitHub ` 、` SourceTree ` 上进行 ` CodeReview ` 的时候,只能看到发生改动的地方,想要查看改动点对应的上下文时非常麻烦(网页上要不断的点展开)。今天给大家介绍一个我们小组内 ` CodeReview ` 时用到的工具及其配置,如果你有其它方式,欢迎一起交流探讨。确保配置前已安装好 ` SourceTree ` 以及 ` Kaleidoscope ` ,配置方式如下
205+
206+ * 点击 ` Kaleidoscope ` 菜单 –> 点击 ` Integration ` –> 下载 ` ksdiff ` (点击 ` Read More ` )
207+
208+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/7-1.jpg?raw=true )
209+
210+ * 安装完成之后,删除 ` ~/.gitconfig ` 文件中 ` difftool ` 与 ` mergetool ` 相关配置(删之前最好备份一下原文件)
211+
212+ * 打开 ` SourceTree ` 的偏好设置,按下图的方式配置。两处 ` Command ` 都填 ` /usr/local/bin/ksdiff ` ,` Argument ` 分别为 ` --partial-changeset --relative-path "$MERGED" -- "$LOCAL" "$REMOTE" ` 、` --merge --output "$MERGED" --base "$BASE" -- "$LOCAL" --snapshot "$REMOTE" --snapshot ` 。这两个参数也可以按自己的需求来配置。
213+
214+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/7-2.jpg?raw=true )
215+
216+ * 以上设置完成之后可以给 ` SourceTree ` 加一个自定义动作,快捷键按自己的喜好设置,参数项填 ` difftool -y -t sourcetree $SHA HEAD ` 即可。
217+
218+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/7-3.jpg?raw=true )
219+
220+ 以上配置完成之后就大功告成了,使用方式就是在 ` SourceTree ` 中选中一个非 ` HEAD ` 的 ` commit ` ,然后按下快捷键,就会在 ` Kaleidoscope ` 打开所有改动过的文件。
221+
222+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/7-4.jpg?raw=true )
223+
224+ Swift 4.0 中 Dictionary 编码成类数组结构的字符串
225+ ----
226+
227+ 在Swift 4.0中,使用` Codable ` 来编码一个` Dictionary ` 时,某些情况下得到的可能并不是类似于字典/对象结构的字符串,而可能是一个类似数组结构的字符串,如下代码所示:
228+
229+ ``` swift
230+ let dict: [Float : String ] = [
231+ 18.0 : " ff0000" ,
232+ 20.0 : " 00ff00" ,
233+ 21.0 : " 0000ff"
234+ ]
235+
236+ let encoder = JSONEncoder ()
237+ encoder.outputFormatting = [.prettyPrinted , .sortedKeys ]
238+ let encoded = try ! encoder.encode (dict)
239+ let jsonText = String (decoding : encoded, as : UTF8 .self )
240+ print (jsonText)
241+
242+ // [
243+ // 21,
244+ // "0000ff",
245+ // 18,
246+ // "ff0000",
247+ // 20,
248+ // "00ff00"
249+ // ]
250+ ```
251+
252+ 这里的` dict ` 以` Float ` 类型为` key ` ,结果是输出一个类似数组的字符串。查看源码中` Dictionary ` 对` Encodable ` 协议的扩展实现,如下代码所示:
253+
254+ ``` swift
255+ extension Dictionary : Encodable /* where Key : Encodable, Value : Encodable */ {
256+ public func encode (to encoder : Encoder) throws {
257+ assertTypeIsEncodable (Key .self , in : type (of : self ))
258+ assertTypeIsEncodable (Value .self , in : type (of : self ))
259+
260+ if Key .self == String .self {
261+ // Since the keys are already Strings, we can use them as keys directly.
262+ var container = encoder.container (keyedBy : _DictionaryCodingKey.self )
263+ for (key, value) in self {
264+ let codingKey = _DictionaryCodingKey (stringValue : key as! String )!
265+ try (value as! Encodable).__encode (to : & container, forKey : codingKey)
266+ }
267+ } else if Key .self == Int .self {
268+ // Since the keys are already Ints, we can use them as keys directly.
269+ var container = encoder.container (keyedBy : _DictionaryCodingKey.self )
270+ for (key, value) in self {
271+ let codingKey = _DictionaryCodingKey (intValue : key as! Int )!
272+ try (value as! Encodable).__encode (to : & container, forKey : codingKey)
273+ }
274+ } else {
275+ // Keys are Encodable but not Strings or Ints, so we cannot arbitrarily convert to keys.
276+ // We can encode as an array of alternating key-value pairs, though.
277+ var container = encoder.unkeyedContainer ()
278+ for (key, value) in self {
279+ try (key as! Encodable).__encode (to : & container)
280+ try (value as! Encodable).__encode (to : & container)
281+ }
282+ }
283+ }
284+ }
285+ ```
286+
287+ 可以看到当 ` key ` 的类型为 ` String ` 和 ` Int ` 时,使用 ` _DictionaryCodingKey ` 来编码 ` key ` ,进而编码 ` key-value ` 对,最后以类似字典的结构输出(依赖于 ` keyed container ` ),这是因为在 ` Codable ` 系统中,这两个类型是有效的可编码 ` key ` 类型;而其它类型则不是,由于 ` Dictionary ` 无法告诉其它类型如何编码自身,所以将这些值 ` key ` 存储在一个 ` unkeyed container ` 中,最终处理成一个数组。
288+
289+ 参考:
290+
291+ 1 . [ UnkeyedEncodingContainer] ( https://developer.apple.com/documentation/swift/unkeyedencodingcontainer )
292+ 2 . [ Why Dictionary sometimes encodes itself as an array] ( https://oleb.net/blog/2017/12/dictionary-codable-array/ )
293+
294+ CoreAnimation 与 pop 的对比
295+ ----
296+
297+ 最近在 ` Medium ` 上看到一篇《Should you use POP?》的文章,文章主要通过以下几个方面来对比了 ` pop ` 和 ` Core Animation ` 。
298+
299+ * ` Core Animation ` 工作原理:每次添加动画时 ` QuartzCore ` 会打包其参数,然后通过进程间通信的方式传递给一个名为 ` backboardd ` 的后台进程。然后该进程通过 ` OpenGL ` 渲染和处理 ` layer ` 的层级以及 ` layer ` 上的动画。最重要的一点就是该进程完全独立于你的应用,应用只会拿到动画开始和结束的回调(` CAAnimationDelegate ` ),不负责动画的渲染(显式动画除外)。也就是主线程和 ` CoreAnimation ` 不会互相影响,也就是即使主线程阻塞了,` CoreAnimation ` 依旧在执行。
300+
301+ * ` pop ` 的工作原理:使用 ` CADisplayLink ` 来开启一个 ` fps=60 ` 的渲染工作。每当 ` CADisplayLink ` 回调触发时,更新一下动画的进度。也就是每一帧发生改变时都需要通知 ` backboardd ` 来渲染,因为它对于 ` layer ` 的变化并不知情。
302+
303+ * 由于 ` pop ` 必须在主线程上处理动画,所以 ` pop ` 动画很有可能发生卡顿。作者写了一个 ` Demo ` 来演示对应效果,效果如下图,左边为 ` Core Animation ` 的方式,右边为 ` pop ` 的方式。
304+
305+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/9-1.gif?raw=true )
306+
307+ * 作者对比了 ` Core Animation ` 和 ` pop ` 的性能。同样动画效果情况下(运行10s),使用 ` Time Profiler ` 看 ` backboardd ` (` CoreAnimation ` ) 和应用(` pop ` ) ` CPU ` 消耗,` iPhone4 iOS7.1.2 ` 和 ` iPhone6 iOS8.1.1 ` 的对比结果下图所示(左边 ` iPhone4 ` ,右边 ` iPhone6 ` )。可以看出两者 ` backboardd ` 进程的 ` CPU ` 耗时差别在 ` 100ms ` 左右,但是应用的 ` CPU ` 耗时差距十分明显,` Core Animation ` 应用 ` CPU ` 耗时接近于0。
308+
309+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/9-2.jpg?raw=true )
310+
311+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/9-3.jpg?raw=true )
312+
313+ * 结论如下图所示。` Core Animation ` 优点为:①单独进程运行 ②不会阻塞主线程。缺点为:①复杂动画效果要写冗长的代码 ②手势驱动动画比较复杂。 ` pop ` 的优点为:①丰富的 API ②内置很多的动画 缺点为:①在主线程上执行 ②动画过程可能卡顿 ③消耗更高的 ` CPU `
314+
315+ ![ ] ( https://github.com/southpeak/iOS-tech-set/blob/master/images/2017/12/9-4.jpg?raw=true )
316+
317+
201318
202319宏中的 ## 的含义
203320----
@@ -250,6 +367,7 @@ static BOOL const KTVHCLog_##target##_ConsoleLogEnable = console_log_enable;
250367}
251368```
252369
370+
253371iOS快速解析崩溃日志
254372----
255373** 作者** : [ Vong_HUST] ( https://weibo.com/VongLo )
0 commit comments