搬家卖书

这两年买纸质书买的越来越少了。但是有些书没有电子版还是要买纸质的。

很多书买的时候都很兴奋,但是经常买回来看两眼就放弃了。趁着这次要搬家的机会,打算把珍藏多年的一些纸质书卖了,一方面让这些书继续发光发热,另一方面通过这个也能交到一些志同道合的朋友,也算是一举两得啦。

新书5折,旧书3折。相关书目如下,深圳面交,先到先得。

  • mac相关

    • Cocoa Programming for OS X (英文原版书,原价49.9 dolar)
    • AVFoundation开发秘籍(主要讲Mac/iOS平台音视频相关技术)
    • 硅谷革命 (讲述Mac机的研发历史,之前在极客时间买的)

test

  • 网络相关

  • 测试相关

  • 深度学习&算法

  • 人文类

  • UI设计

    • about Face 最新英文原版 (原价50 dolar)

  • 其他杂类

注释和共享

macOS上的进程间通信的方案很多,总的来说分为以下三种,如下图所示

IPC

  • 第一种也是历史最悠久的是基于POSIX的实现,其中常见的是基于Socket (TCP/IP)的实现。同时这种方案和平台无关。
  • 第二种基于 底层信号机制,mac系统的内核组件就是使用mach_mag来传递消息。参考
  • 第三种就是Foundation库里提供的一些类库。github上有个不错的范例实现基于CFMachPort—https://github.com/Syphon/Simple​

XPC方式

估计是苹果觉得这些方案,都不够好,要么不够易用,要么不够安全。所以在2011年的时候推出的全新的XPC进程间通信的方案。

The XPC Services API provides a low-level (libSystem) interprocess communication mechanism based on serialized property lists.

这是一套C的API,范例代码可以参考https://github.com/objcio/issue-14-xpc

但是这个技术有一个挺大的局限性,XPC进程只能是一个不带界面的控制台进程。关于 XPC 比较特别的尝试可以看看这个代码: https://github.com/OpenEmu/OpenEmuXPCCommunicator

这可能一般的简单的程序架构是没问题的,但是有些特殊的要求,比如我就要求主程序和子程序都是界面程序 并且可以互相调用,这样子就完全搞不定了,由于XPC这套东西并不开源,所以要实现这种更灵活的互相调用,只能另辟蹊径。

为了实现这种两个界面程序,主程序和子程序可以互相调用的需求推荐就采取 Socket的方式实现,因为这种最标准的方式和操作系统无关,相比其他方案 不会因为 系统API被废弃而 变得不可用。

Socket方式

一个理想的调用关系大概是这样的:

子程序放在主程序的程序包内。

当主程序需要调用子程序时 主程序先创建一个 TCP Server,并且把Server的地址和端口 作为参数 调起子程序(NSTask)。

子程序启动后,获取参数中的TCP地址和端口, 然后创建TCP Client进行连接。然后通过TCP的通信来互相调用。

至此 通信层的功能和大体框架基本确定了。

那应用层应该以何种方式调用呢?是否要定义一个特别的通信规约?

如果定义了通信规约,那每次别人要使用这套框架的时候还要先熟悉一下规约,这就显得不灵活 和 不易用了。有没有可能借用XPC的思路,直接以Objc消息传递的方式来互相调用呢?借助于Objective-C的runtime,这是可以实现的。我个人XPC的内部实现思路估计也是一样的。

先复习一下Objc的消息转发流程:

注意最后一步 forwardInvocation 可以获取函数的所有调用参数。

-(void)forwardInvocation:(NSInvocation *)anInvocation;

假如 主程序利用 forwardInvocation 把需要调用的子程序的 函数信息 序列化 通过 Tcp 传递给子程序,子程序 反序列化后再根据函数信息调用对应功能。这就完成了一个互相调用的过程。

实现对应功能的时候注意一下 NSInvocation 在Swift已经被废弃了,所以相关功能只能使用OC编写。

另外 NSInvocation 在ARC环境下跑的时候有个坑,可以参考一下 nsinvocation-and-arc-automatic-reference-counting

具体的代码就不放上来,大家有兴趣可以按照上述思路 实现一下看看,一方面可以熟悉一下TCP流程,另一方面也可以熟悉 OC的 转发流程,另外实现完这一套之后 也会 对苹果XPC内部实现有一定的了解。

参考链接:

注释和共享

最近对mpv的源码产生了兴趣,打算研究研究。

mpv是属于一个大型的C语言的跨平台的播放器项目,其代码源自MPlayer和mplayer2,是一个历史非常悠久的项目了。

先来分析一下此项目大致存在的难点:

  • 针对跨平台的编译处理。
  • 运用了C语言的奇淫巧技。
  • 图形学的一些专业知识,主要是编解码、图形渲染等。

先从github上下载了mpv的源码,然后进行编译,整个过程比较人性化。

waf编译系统

mpv项目自己定制了一个叫waf的编译系统,至于为什么使用waf编译系统在他们的项目文档里有做介绍why waf,总结下来大致以下几点:

  • 编译脚本 在跨平台时比较保持一致的代码,并且尽量减少重复和胶水代码。
  • 配置(configuration)步骤 和 编译(buid)步骤必须是分离的。
  • 脚本比较好理解、好修改。(waf使用python编写)

源码编译

(本文的编译过程基于Mac)先从github上下载了mpv的源码。

第一步先跑个脚本下载最新的waf执行文件。

1
./bootstrap.py

第二步跑一下waf的configuration步骤,这个过程会告诉你缺少哪些组件。

1
./waf configure

根据第二步的结果,对一些缺少的组件进行安装。

1
2
brew install libass
brew install ffmpeg

然后 再跑一遍 ./waf configure 就成功生成了config.h,用于最后的编译过程。

在configure阶段可以使用下列选项,不进行代码优化,便于后续调试。

--disable-optimize

第三部 跑一下build步骤,这样就生成了最终的执行文件了。

1
./waf

最后一步 运行一下 安装步骤,就把mpv 放到了 /usr/local/bin/mpv 系统目录。

1
./waf install

代码调试

安装好mpv之后,就可以先尝试运行一下程序,可以正常的播放视频。

1
mpv  xx/xx.mp4

接下来尝试用lldb来调试一下代码。由于mpv在mac系统上运行,所以代码的入口在 xx/mpv/osdep/macosx_application.m 这个文件。所以先用lldb在这里设置一个断点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#Launch a process for with arguments a.out 1 2 3 without having to supply the args every time
lldb -- mpv xx/xx.mp4

#enter lldb env then set breakpoint
breakpoint set --name cocoa_main

#star debug
run

#运行结果
* thread #1, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1
frame #0: 0x00000001000d711b mpv`cocoa_main(argc=2, argv=0x00007ffeefbff940) at macosx_application.m:338 [opt]
335
336 int cocoa_main(int argc, char *argv[])
337 {
-> 338 @autoreleasepool {
339 application_instantiated = true;
340 [[EventsResponder sharedInstance] setIsApplication:YES];
341
Target 0: (mpv) stopped.

这之后 就可以一边看代码一边通过调试来理解代码行为了。

最后再补充几条常用lldb的命令,更多内容可以查看lldb的官方文档。

1
2
3
4
5
6
7
8
9
10
# Show the stack backtrace for the current thread
thread backtrace

# List all breakpoints
breakpoint list

# Delete a breakpoint
breakpoint delete 1

breakpoint disable/enable

注释和共享

Live photo是近两年来我最喜欢的新特性之一(只能在iPhone 6S/SE上使用)。

它的功能简单来说就是拍一张照片时候 顺便 记录拍摄瞬间 1~2秒的视频。这就非常有用了,原因有这么几个:

  1. 有人被拍的时候就喜欢眨眼,有了这个功能就可以在在视频的关键帧中挑一张不眨眼的靓照做为主图像。
  2. 一般拍照的时候 都是 精彩瞬间,所以5、6张live photo完全可以直接组合成一个有趣的视频,而静态图片是做不到的。

如何生成Live Photo

其实live photo内容构成很简单,就是 JPG + MOV,即一张高清大图,加上一段720P的视频。

所以如果你要自己制作一个live photo也很简单,LoveLiver 这个开源软件可以选择一个视频,然后把其中一段转换成live photo,并导入到系统的Photos中。

2

Live Photo导入iMovie/Final Cut Pro

虽然Live Photo这么好,但是苹果原生的iMovie/Final Cut Pro却不支持直接导入,真是坑爹。

只能曲线救国,通过系统 原生应用 Image Capture.app(在 spotlight搜索 image即可找到) ,插入手机 连接线,然后选择对应的Live Photo,然后点击 Import,它会下载到指定的文件夹里。

1

最终Live Photo会导入成 JPG + MOV,还有可能有AAE文件(这是个XML文件,记录着这张照片的修改信息),然后你把对应MOV文件导入到iMovie/Final Cut Pro就完成任务啦。

注释和共享

I Hired Myself

ATP 259期 I Hired Myself 中Casey 提到他写了一个“Mac App”(其实是个命令行工具)用于管理他的照片流,让他有种I Hired Myself的感觉。我听了之后也很有感触,这也是我选择 当程序员的初衷。

我的照片流

今天谈一谈Mac上导入照片工作流,其中利用到了ImageCaptureCore框架,功能原理如下:

1

这个框架支持手机 以及 相机的SD卡,一般的应用场景是

  • 插上相机的SD卡

  • 电脑自动检测到且自动打开photos这个Mac上的原生图片工具

  • 然后列出SD卡里的所有照片


    之后,你可以选择 照片 导入到Mac里。photo里还提供了导入后删除的选项。

不知道各位第一次使用的时候什么感想,反正我当时是被惊艳到了。

至此之后 我就喜欢上了这样的照片管理流程。

  • 我会定期把 相机 和 手机导入到 Mac里,然后把源文件删除。
  • 然后定期 对 Mac 进行TimeMachine 备份,这样就同时把照片给备份了。
  • 然后每次浏览 Mac的照片库的时候 都会标注 为 最喜爱 的照片。
  • 同时把所有最喜欢的照片 添加到 iCloud photo Sharing里。这样我和女朋友都可以在photo的共享里找到这些照片。

这样做有很多好处:

  • 还是使用 5G 的iCloud空间就够了。
  • 可以定期清理 手机 中大量照片占用的空间。
  • 照片进行了定期备份。
  • 相机 和 手机的照片可以统一存放处理。
  • 在任意设备 都可以获取 自己挑选的最喜欢的照片。

ImageCaptureCore

下面再来说说ImageCaptureCore, 其实Photos里的那一系列功能都是 通过它实现的。
它的主要结构如下,基本上是提供了一个树形结构 方便 你来处理导入 照片。
2
大家有兴趣可以下载 苹果的范例程序CameraBrowser来研究一下。

注释和共享

  • 第 1 页 共 1 页

max Lin

make complex simple


Developer


shenzhen