使用 Gost 创建 SOCKS5-TLS 代理

首先安装 Docker,安装教程参考官方文档 https://docs.docker.com/install/

安装完成后,拉取 Gost 镜像

1
docker pull ginuerzh/gost

安装 acme.sh,用于申请证书,申请证书的过程参见 README,写的很详细,RSA 或者 ECC 证书都是可以的

申请完证书后安装证书,这里将证书安装在 /etc/gost/,这个路径在使用 docker 运行 Gost 时会用到

1
acme.sh --install-cert -d "domain.com" --fullchain-file /etc/gost/cert.pem --key-file /etc/gost/key.pem

创建 secrets.txt 文件,用于多用户认证,格式为一行一对用户名密码,空格隔开,如

1
2
user0 pass0
user1 pass1

这里为了方便将 secrets.txt 文件也放在 /etc/gost/,方便挂载,可以根据自己情况修改

运行 Gost

1
[sudo] docker run -d -p 8888:8888 --name gost -v /etc/gost/:/mnt ginuerzh/gost -L="socks5+tls://:8888?cert=/mnt/cert.pem&key=/mnt/key.pem&secrets=/mnt/secrets.txt"

其中 -v 参数用于挂载当前用户的 /etc/gost/ 到 Gost 运行环境的 /mnt 目录,这样 Gost 程序就可以读取证书和用户信息文件,8888 是端口,这个根据自己的情况适当修改即可

运行后查看 Gost 运行状态,如果出现以下提示,就运行成功了

1
2
3
~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0b95ed614bb1 ginuerzh/gost "/bin/gost -L=socks5…" 21 minutes ago Up 21 minutes 0.0.0.0:5877->5877/tcp gost

参考资料:

关于 weakSelf 和 strongSelf

关于 weakSelf 和 strongSelf

block 带来了一定程度的便利性,在作为回调使用时,时常会遇到内存问题,即「引用循环」,这在 Objc 中是一个绕不开的话题。

试着看如下场景:

1
2
3
4
5
6
7
8
9
10
DemoViewController.m

- (void)viewDidLoad {
[super viewDidLoad];
CustomView *v = [[CustomView alloc] init];
[self.view addSubview:v];
v.callbackBlock = ^{
[self doSomething];
}
}

viewDidLoad 方法执行时,创建一个 block 并赋值给对象 vcallbackBlock 属性,callbackBlock 捕捉 selfself 持有 self.view, v 在 addSubview 后成为 self.view 的子 view 而被 self.view 持有,这样就形成了一个引用循环,如下:

Xcode 合并冲突后 Discard All Changes 导致代码丢失问题

使用 Git 合并时常会产生冲突,某些情况下我们想丢弃此次合并,通常会使用 git reset --hard HEAD 命令来重置,其实 git reset --hard HEAD 命令在此时不光重置了暂存区,还结束了丢弃了这次合并,和 Xcode 的 Discard All changes 行为和 git reset --hard HEAD 并不完全一致,只是重置暂存区而没有结束 merge,接下来的 commit 将自动完成这次 merge,因为同时重置了暂存区,最终造成代码丢失。下面用一个 demo 来重现和解释这个现象。

macOS 计划任务的一些问题

最近在搞一个小东西,搞这个东西呢,想达到的效果如下:

  1. 定时更新仓库代码
  2. 根据最新一条 commit 的 message 中是否包含特定字符串来决定是否打包
  3. 打包过的 commit 不再打包
  4. 打成成功后过滤一下与上次打包之前 commit 的日志,并作为邮件内容发送给特定的人
  5. 打包失败了把日志发给我自己

大体上功能就是这些,不过有一些细节要处理,诸如打包要生成的文件放的目录存在与否,打包成功后的 commmit sha1 值记录方式等,搞定这些后,剩下最后一步,打包机没有放在公网,也就没有 IP 地址,所以也不能使用 Webhook 来及时知道仓库有代码更新,只好轮询了,脚本负责更新代码和打包,定时轮询这个交给系统的计划任务就好,但是这最后一步远没有想的那么简单。

升级 macOS Sierra 后 Vim 和 Tmux 异常的解决办法

尝鲜的代价大概就是要先踩坑,苹果在 9 月 7 日的发布会后,发布了包括 macOS,iOS 和 tvOS 在 GM 版和候选发布版,这种版本在没有大 bug 的情况下,一般就是正式版了,也就是足够稳定了,就算不稳定也不会和正式版差很多,然后我就升级了,升级后一些软件不能正常工作,这里记录一下。

首先主要是键盘映射类的,因为 Sierra 上对键盘和鼠标的驱动发动较大,导致了与其相关的软件基本都不能正常工作,这个在之前的文章中有提到,见 在 macOS Sierra 上替换 CapsLock 键为 Escape 键 好在找到了解决办法。

Git 父提交

使用 Git 的时候,如果需要重置本地目录到最新一次提交,一般会使用以下命令:

1
git reset --hard HEAD

一直以来我都以为 HEAD 是最新一次提交,那么 HEAD^ 就是倒数第二次提交,和 HEAD^ 类似的 HEAD~1 也是最近一次提交,HEAD~2 是倒数第二次提交,这样理解看起来似乎没有问题,因为一次次的使用证明 HEAD^ 就是倒数第二次提交,直到在一个比较复杂的项目里想打印最近 10 条提交的 log,使用以下命令:

在 macOS Sierra 上替换 CapsLock 键为 Escape 键

根据 Karabiner 作者的描述,macOS Sierra 对键盘和鼠标的驱动的修改和 Karabiner 有冲突,所以现在 karabiner 在 macOS Sierra 上不能工作了。

macOS 10.12 changes of the generic keyboard and mouse drivers made a great impact on Karabiner and Seil.
We should make a large changes in Karabiner and Seil architecture.
There is not a workaround for this issue.

Please wait an update of Karabiner and Seil for macOS 10.12.
(It may take a long time.)

引用自:https://github.com/tekezo/Karabiner/issues/660#issuecomment-226942420

作为一人每天使用这个软件的我简直是晴天霹雳啊,现在对键盘的使用习惯是把 CapsLock 键映射成 Control 键,并在只按左边的 Control 键时,等同于 Escape 键,这样用起来比较顺手,对于使用 Vim 较多的人来说,使用 CapsLock 替换掉 Escape 可以省去左手在键盘上跑来跑去。作者说要适配 macOS 10.12 要做的修改很大,已经在进行中了,新开了一项目:https://github.com/tekezo/Karabiner-Elements ,作者建议现在不要用在自己的电脑上,所以,先找替代方案吧。

使用 Autolayout 实现动态高度 UITableViewCell

在 Frame 布局时代,如果要实现一个动态高度的 Cell,需要给 Cell 绑定数据后,根据内容的展示情况计算得到 Cell 的高度,最好再加一个高度缓存,因为这种计算在 UITableView 滑动时代价还是比较高昂的。那么配合 Autolayout 可不可以实现动态高度 Cell 呢?当然是可以的。

使用 sed 匹配和替换字符串

sed 可以方便的进行批量替换文件中字符串操作

1
sed "s/ww2/ws3/g" *.m

以上命令就是将当前目录下所有 .m 文件中的 ww2 替换为 ws3,并打印出来。

sed 中 如果需要覆盖当前文件,可以加上 -i 参数
例如:

1
sed -i "s/ww2/ws3/g" *.m