关于 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

Jenkins 中 对 Git 日志过滤

Jenkins 中想对某次构建中的 Git 的日志进行过滤后使用,首先需要拿到上次构建成功的 Git HASH 值,Jenkins 提供了这样的一条链接,可以拿到上次构建成功时的一些信息:

1
http://<host>/job/<job_name>/lastSuccessfulBuild/api/xml

可以使用 curl 拿到 XML 文件的内容:

1
curl --silent --user $USER:$API_TOKEN $URL | grep "<lastBuiltRevision>" | sed 's|.*<lastBuiltRevision>.*<SHA1>\(.*\)</SHA1>.*<branch>.*|\1|'