Phenmod Zhu's Blog

注意你的注意力

Brew 的工作细节

本文将大略讲一下 brew 的工作细节。对普通的使用者来说,只要看明白使用文档就好,了不了解这些内容并不重要。有些内容(用斜体标出的部分)我也不太确定是否正确,还待后续修改。

brew 本身的文件位置

通过 which brew 命令,可以发现 brew 命令的可执行文件的路径为 /usr/local/bin/brew,它是个 shell 脚本。用文本编辑软件打开,可以发现它实际上是读取系统使用的 ruby 的路径,来执行 /usr/local/Library/brew.rb。

brew 软件本身的各个文件 全部 在 /usr/local/Library 目录下,可以在它的三个子目录 bin/、Library/、share/ 下找到安装后的 brew 文件。比如,/usr/local/bin/brew 就是 brew 的可执行文件。具体每个brew的子命令都是一个个的 ruby 脚本,比如,brew search 就是 /usr/local/Library/Homebrew/cmd/search.rb。

每个使用brew安装的软件都有一个对应的ruby脚本,我们称为 Formula,brew install <package_name>安装命令其实就是读取这个脚本里的配置,下载源码,然后运行配置里写好的安装命令。这些脚本放在 /usr/local/Library/Formula 下,使用 brew update 从github拉取最新版本的 brew 时,会在命令行运行结束后看到提示,哪些软件有版本更新,新增了哪些软件。

brew 安装软件的细节

软件下载下来之后,缓存在 /Library/Caches/Homebrew 目录中,你会在这个目录下发现一堆你下载过的软件包。如果你已安装某软件,然后用 brew reinstall <package_name> 重新安装该版本,就不需要重新下载了,它会直接使用已下载的软件进行安装。

brew 大多是直接下载源码然后编译安装,安装命令如 ./configure && make install。并且,在安装本软件之前,会先安装脚本里指明的本项目的依赖库。

软件安装的目录是 /usr/local/Cellar/<package_name>/<version>/,比如 /usr/local/Cellar/autojump/22.2.4/。源码编译完成后,生成的文件都会放在这里,如果是直接下载的可执行文件,也会直接放在这里。每个版本的软件都会放在对应版本名称的文件夹下。一般的软件可能会包含可执行文件、供其它库使用的头文件、运行库、文档等文件或目录,为了方便升级管理,,brew 会把这些文件或目录分别软链接到 /usr/local/bin/、/usr/local/include/、/usr/local/lib/、/usr/local/share/ 等目录下。

如果你用 brew upgrade <package_name> 更新过几次该软件,你所有安装过的版本都会在 /usr/local/Cellar/<package_name>/ 目录下找到。每次升级时,brew都是先把可执行文件等都编译到当前版本目录下,撤销之前版本的软链接,然后再将新版本软链接到 /usr/local 的各子文件夹下。这样,我们就会使用到最新版本了。

你也可以使用 brew swith 来切换使用软件的某具体版本。比如,brew swith autojump 22.1.4

时间久了,你的安装文件会越来越多,这时候可以用 brew cleanup 清理掉不想用的旧版本,这样会会节省出来大量硬盘空间。如果你不想直接删掉,可以使用 brew cleanup -n 命令,它相当于预演一下,告诉你真正运行 brew cleanup 时会干些什么,而不会真正执行。检查完毕确定可以删除后,你再 brew cleanup 就安全多了。brew 的很多命令都支持 -n 参数,也就是 --dry-run 参数,这些就需要你自己去翻文档了。

brew 还提供了很多其他命令,有需要的话自己 man brew 查看吧。

用 Brew 安装管理软件

看看 brew 官网的介绍

The missing package manager for OS X

Mac OS 没有提供软件包管理器,不能像在 linux 上能使用 apt-get 那样,从软件仓库中搜索、安装、升级软件。就有大神 Max Howell 写了个 brew。

brew 项目在 github 上的地址是 https://github.com/Homebrew/homebrew,brew 本身及每个软件的版本更新维护都是在这里通过提 pr 的方式进行。

安装

1
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

常用命令

1
2
3
4
5
6
7
8
9
10
11
brew search <package_name>      # 搜索
brew install <package_name>     # 安装一个软件
brew update                     # 从服务器上拉取,并更新本地 brew 的包目录
brew upgrade <package_name>     # 更新软件
brew outdated                   # 查看你的软件中哪些有新版本可用
brew cleanup                    # 清理老版本。使用 `-n` 参数,不会真正执行,只是打印出真正运行时会做什么。
brew list --versions            # 查看你安装过的包列表(包括版本号)
brew link <package_name>        # 将软件的当前最新版本软链到`/usr/local`目录下
brew unlink <package_name>      # 将软件在`/usr/local`目录下的软链接删除。
brew info                       # 显示软件的信息 
brew deps                       # 显示包依赖

brew 的子软件包

我们常用的其实是 brew 的主包,里面有比较常用的软件,比如 erlangcloccmaketree等。但还有些比如科学计算相关的软件,并不是很常用,数量又很多,就会根据类型单独分到一个子软件包里。在安装 brew 的时候,并不会将这些软件的 Formula 下载到本地,要想使用的话,应该先安装该子软件包。

比如 opencv 在 science 子软件包里,安装的时候需要先使用命令 brew tap homebrew/sciencescience 子软件包下载下来,然后再 brew install opencv。或者你也可以直接指明软件所在的子包,通过 brew install homebrew/science/opencv 命令来安装,这个命令会先 tap 该子软件包,再安装软件。homebrw/science 项目的 github 地址是:https://github.com/Homebrew/homebrew-science,tap下来的 science 的 Formula 放在 /usr/local/Library/Taps/homebrew/homebrew-science 目录下。

你可以在 github 上看到 brew 的其它子软件包:https://github.com/Homebrew,比如 homebrew-gameshomebrew-emacs 等。

使用 brew cask

brew 会对依赖的软件也进行安装,并且配置环境,再复杂的安装也就是一条命令而已,这对需要安装各种运行环境的程序员来说,简直是天大的福音。但 brew 是通过下载源码的方式进行安装的,alfred、dropbox、chrome 等软件能使用 brew 直接安装软件么?答案是可以的,有工具 brew cask。

官网地址:caskroom.io

github地址:brew cask

它扩展了 brew,以优雅、简单、快速地安装和管理 OS X 图形界面程序为己任,目前已收集了 2941 个常用软件,并有 433 个维护人员。

brew tap caskroom/cask              # 添加 github 上的 caskroom/cask 库
brew install brew-cask              # 安装 brew-cask
brew cask install google-chrome     # 安装 chrome 浏览器
brew update && brew upgrade brew-cask && brew cleanup # 更新
brew search <package_name>          # 搜索想要的软件。

brew cask装的软件会放到 /opt/homebrew-cask/Caskroom 下面,然后软链接到 ~/Applications。 跟我们手动安装软件的默认位置 /Applications 不一样。

一些我安装的软件:alfred appcleaner cheatsheet chrome dropbox haskell-platform launchrocket onepassword totalfinder

通过 brew cask 安装 Finder 的文件预览插件

我们可以在 Finder 里选中某个文件后,敲一下空格键,Finder 会弹出一个这个文件的预览窗口,这会让我们直接看到这个文件的内容,而不用打开关闭该文件,在是个非常实用的功能。如果你的 Finder 像我一样始终是以分栏的方式显示的话,在选中文件后,Finder 右侧会直接显示改文件内容,那就更方便了。

但是,支持预览的文件格式只有系统默认的一些如图片、pdf等,还有很多格式的软件,如 json、xml、markdown、html等,我们是不能通过 Finder 的文件预览来查看的。

所以,强烈推荐装一些插件

1
brew cask install qlcolorcode qlstephen qlmarkdown quicklook-json qlprettypatch quicklook-csv betterzipql webp-quicklook suspicious-package

其它

如果你经常使用 Alfred 启动程序,那么你会想 Alfred 可以搜索 brew cask 安装的程序,实现这些仅需运行:

1
brew cask alfred link

此外,你还可以通过 brew cask 安装 launchrocket,来管理通过 brew 安装的 service。

用 ClangFormat 插件格式化 Objective-C 代码

多人开发的工程中,每人负责一部分,代码风格各异。如果没有统一的约定,在阅读和维护其他人的代码时,会有各种不适。一些简单的排版工作,比如空格有几个、括号是否换行等等,也会不必要地浪费一些精力。于是不少公司会使用一些工具对代码进行自动格式化,比如 Dropbox、Parse。

在 iOS 工程中,我们使用 ClangFormat 工具来格式化代码,Xcode 有方便的插件可用。插件地址:https://github.com/travisjeffery/ClangFormat-Xcode

安装

  • 安装 clang-format
1
brew install clang-format
  • 安装 Xcode 插件 ClangFormat-Xcode。可通过 Alcatraz或者直接下载源代码编译运行,然后重启 Xcode 。

  • 下载本人使用的格式配置文件,文件名为 .clang-format,把它放到 /Users/yourname/ 下,你的所有工程都会使用本配置文件。也可单独放到某工程文件夹里,仅限本工程使用。

或者自己使用 clang-format 导出一份配置文件再自己修改。

1
clang-format -style=WebKit -dump-config > .clang-format

注意,文件名最前面有个点,改名后会变为隐藏文件。如果你的 Finder 不能显示隐藏文件,可运行下面两条命令

defaults write com.apple.finder AppleShowAllFiles -bool true
killall Finder
  • 勾选上 Xcode -> Edit -> Clang Format -> File,该插件就会使用我们放到用户文件夹的配置文件对源码进行格式化了。

使用方式

  • 可以手动点选 Xcode -> Edit -> Clang Format -> Format File in Focus 对当前选中的文件进行格式化。也可以选择其它两个选项对当前选中的文本或多个文件进行格式化。
  • 可以选中 Xcode -> Edit -> Clang Format -> Enable Format on Save,使之变为 Disable Format on Save,这样在每次 cmd + s 保存文件时,都会自动格式化文件了。
  • 可以给 Xcode 配置系统快捷键。比如我们可以配置 ctr + i 作为对当前选中文件进行格式化的快捷键。步骤如下:
    • 打开系统偏好设置 -> 键盘 -> 快捷键 -> 应用程序快捷键,并点击 +
    • 设置应用程序为 Xcode,菜单标题为 Format File in Focus,快捷键里按下 ctr + i。当然,你也可以使用为其它命令设置快捷键。

每个人在提交代码之前,必须格式化代码。 用了这个之后,基本上就不用开发者做排版的事情了,哗啦啦写完代码,一键格式化,人生舒爽了很多。

格式配置文件

该插件默认了几种风格可供选用,但都不太符合我们想要的形式,于是自己定义了一个格式配置文件.format

这个是ClangFormat各配置项字段的详细说明,还有个用实例解释各字段的可交互网站

这个是Parse的配置文件,可做参考对比。

我们的这个配置还有很多不足的地方,比如长字符串会因为每行字符数限制被截断成两个字符串,并且每格式化一次,就再多截一段,直至截到某个阶段才不再变化。造成一个好好的字符串,变成了好几个只包含了一个或几个字符的字符串。

关于空行

配置文件里我们现在允许最多连续两行空行,正在考虑只允许一行。

确实有分段视觉需求的,使用pragma mark进行分割,如下:

1
2
3
// =================================================================================================
#pragma mark - <#代码分块注释#>
// =================================================================================================

用它定义个code snippet,来个快捷键(我的是pm),省心啊。

关于每行字符限制

如果你把上面的 pragma 段拷贝到 xcode,会发现上面那一串等号会终止在第 100 列。没错,我们现在每行字符数限制就是 100。

其实我很想定义到 120,但是在某些同学的 macbook air 的小屏幕上不太够显示。

用 Git-flow 做分支管理

关于git-flow

git 鼓励我们多开分支,但是没有一套模型告诉我们如何管理分支,有人总结了一条最佳实践惯例:git-flow,并且提供了一套 git-flow工具来方便我们实践它。该工具的每个命令都能实现数个 git 命令才能实现的功能,使用起来还是比较方便的。

Git flow 開發流程这篇文章介绍了git-flow的入门使用方式。

git-flow 创始人写的关于 git-flow 的文章:A successful Git branching model。里面详细描述了 git-flow 的工作方式。这儿有两篇不错的中文翻译: Git开发管理之道一个成功的Git分支模型

git-flow的cheatsheet,里面列出了常用的命令: cheatSheet

该网页比较直观地展示出每个 git-flow 命令实际都做了哪些操作,值得一看。还提供了中文版,翻译得不咋地。

安装

github上git-flow的安装页

如果在mac上安装了brew,直接用brew安装

brew install git-flow

git-flow-completion

命令行不默认自动补齐git flow命令,安装一个git-flow-completion,它可以让你的Bash、Zsh支持命令行自动补齐,github项目地址在此

我用的oh-my-zsh,它的最新包里面有git-flow插件(~/.oh-my-zsh/plugins/git-flow),这个插件其实用的就是git-flow-completion的内容。修改~/.zshrc的plugins,添加使用git-flow插件即可。我的plugin列表如下

plugins=(git git-flow git-flow-completion python svn xcode ruby perl)

(关于brew和oh-my-zsh,参见文章:mac上常用软件)

使用

init

git flow init [-d] 提示你各个分支的命名及tag前缀。[-d]表示接受所有默认设置。

开发新功能(feature)

based on develop

1
git flow feature start login

develop 分支创建了一个新的分支 feature/login,并自动切换到这个分支下面。然后就可以进行 login 功能开发,中间可以多次的 commit 操作。开发完毕后:

1
git flow feature finish login

feature/login分支的代码会被合并到 develop 里面,然后删除该分支,切换回 develop. 到此,新功能开发这个场景完毕。

1
git flow feature publish MYFEATURE

如果是合作开发,需要发布新特性到远程服务器,其它用户也可以使用这分支。

1
git flow feature pull MYFEATURE

取得一个其它用户发布的新特性分支,并签出远程的变更。

发布上线前(release)

1
git flow release start v0.1.0 [BASE]

git-flow 从 develop 分支创建一个新的分支,做发布前的一些事情,如修改版本号,fix最后的一些bug。

完成后,

1
git flow release finish v0.1.0

git-flow 会依次切换到 master develop 下合并 release/0.1 里的修改,然后用 git tag 给当次发布打上tag v0.1.0。 release分支里的东西会自动合并到master和develop里。

1
git flow release publish v0.1.0

创建 release 分支之后立即发布允许其它用户向这个 release 分支提交见容是个明智的做法。命令十分类似发布新特性。

1
git flow release track v0.1.0

签出 v0.1.0 版本的远程变更

紧急bug修正(hotfix)

1
git flow hotfix start bug1 [BASENAME]

git-flow 从 master 分支创建一个新的分支 hotfix/bug1,并切换到该分支下。接下来要做的就是修复 bug,完成后:

1
git flow hotfix finish bug1 

git-flow 会依次切换到 master、develop 分支下合并 hotfix/bug1,然后删掉 hotfix/bug1。到此,hotfix 完成。

support分支

1
2
git flow support
git flow support start <release> <base>

也是从 master创建的新分支,目前不推荐用。

git-flow 的 feature、release 都是从 develop 分支创建,hotfix、support 都是从 master 分支创建。

用 Git 做版本控制

简介

Git是个分布式版本管理系统,本地自己的机器上有代码库,远程服务器上也有代码库。每个人要做的事情就是把自己的代码提交到本地,再把别人提交到服务器上的最新代码拉到本地,修改冲突之后,再将最终的正确代码再推送到远程服务器上面去。多从这个概念来理解,很快就能上手了。

git、ssh配置及bitbucket账号设置

mac系统有默认git,可以直接使用,从命令行运行以下命令可以见到当前git的版本。 git –-version

为git设置ssh

  1. 运行命令:ssh-keygen ,会让输入名称什么的,直接回车三次即可。运行命令后,出现 ~/.ssh 文件夹,里面有两个文件,分别为 RSA 的公钥和私钥,将公钥文件 id_rsa.pub 里的内容拷贝出来。
  2. 当前我们的代码托管在 bitbucket.org 上,需要你注册一个bitbucket.org账号。
  3. 进入 bitbucket 的个人账户管理页面,找到 “SSH Keys",点击 "Add key",将第一步中 id_rsa.pub 里的内容粘贴进去。

参见:

试用一下

配置完成之后自己新建个工程传到 bitbucket 上去,并且试用一下其基本功能。

我们最常用的就是下面这几个命令:

1
2
3
4
5
git add .                          # 如果有新添加的文件,将这些文件添加到本地版本库
git commit -am "changed something" # 然后将代码提交到本地代码库
git pull origin develop            # 把服务器代码库上 develop 分支的最新代码拉下来,自动合并到本地代码库的 develop 分支
……                                 # 如果有冲突,修改冲突代码,然后再次 commit
git push origin develop            # 将本地develop分支的代码提交到服务器的 develop 分支

有了上面这四个,基本的功能就可以实现了。

从服务器上拉下最新代码之前,如果不想提交当前代码,可以这样:

1
2
3
git stash                   #将当前工程暂存
git pull origin develop     #更新远程服务器上的代码到本地
git stash pop               #弹出刚才暂存的当前工程,合并代码

推荐教程

  1. Git Magit:很简单很优秀的一个入门教程。
  2. Git 教程:另一个浅显易懂的教程。
  3. 图解 Git:常用命令的工作原理,有助于透彻理解。
  4. Git 详解:比较全面的介绍了Git的使用。
  5. Pro Git:git官网上的书,覆盖全面,深入浅出,原理介绍得透彻。推荐通读。
  6. Git Community Book 中文版

分支管理方案

Git 鼓励大量使用分支开发,但是分支多了容易乱,我们使用一套比较成熟的分支管理方案 git-flow,详情参见

使用 Git-flow

Mac 下推荐的软件

传说中,Mac 电脑是程序员专用的“飞机中的战斗机”,baidu 一下 “mac 软件推荐”,你会得到很多优秀的工具。下面是我常用的几款,具体安装及使用方式不细说。

  1. 终端工具 iterm,官网下载安装。preferences -> Keys -> HotKey,设置一个系统热键。(我的是cmd+shift+m)。
  2. 终极 shell oh-my-zsh 。安装命令:curl -L http://install.ohmyz.sh | sh,具体使用参考池建强的文章
  3. SourceTree :git的图形化操作工具。
  4. brew :Mac下安装常用软件的利器,几乎所有的软件我都是用它安装管理的。参见用 Brew 安装管理软件
  5. Alfred :自定义各种快捷操作,神器。
  6. Moom :快速设置窗口的位置及大小,全键盘流的福音。
  7. Parallel Desktop :想安装个虚拟机就用它吧,无缝连接系统,牛叉无比。
  8. RescueTime :关注你每天时间的使用,提高工作效率。
  9. Charles :抓包工具,可给真机做代理,可模拟网络不好的情况。
  10. Sublime Text :你永远都不会知道这个看起来像个简单文本编辑器的编辑器有多牛逼。一堆堆的插件。支持 Dash 集成。
  11. Mou :写 markdown 文档,编辑时同步预览比较方便。但是最新版在编写大文件时会比较卡。我现在用 Sublime 装上Markdown ExtendedMarkdown PreviewMarkdownEditingMarkdownTOC这几个插件,编辑预览什么的,也很方便。
  12. iTools :不越狱查看真机 app 里的个各种文件。
  13. XtraFinder :增强 Finder 功能。
  14. cheatSheat:长按 command 查看当前程序的所有快捷键,好用到爆。
  15. Sequel Pro:连接远端、本地 mysql,方便易用。
  16. AppCleaner:应用程序卸载工具。

另外的几个相关推荐帖子:

iOS新人入门文档目录

软件推荐

版本控制:Git 及 git-flow

代码风格

iOS技术

开发工具

开发技术

  • 了解项目框架及用法。
  • 研究ARC的相关技术及使用。熟悉 weak,strong 等关键字的使用。
  • 研究 block 的使用,理解内存的循环引用。
  • 熟悉 StoryBoard 及 Xib 的使用。
  • 全面认识 UIView 及 UIViewController 的各属性功能类的函数功能。
  • 透彻理解 MVC。了解常用设计模式。
  • 了解 UIView 动画及 Core Animation 的主要知识点。
  • 研究线程安全,了解系统类中哪些是线程安全的,了解如何写一个线程安全类。

阅读目录

  • Advanced Memory Management Programming Guide
  • Blocks Programming Topics
  • Cocoa Fundamentals Guide
  • Concurrency Programming Guide
  • Event Handling Guide for iOS
  • iOS Human Interface Guidelines
  • Key-Value Coding Programming Guide
  • Key-Value Observing Programming Guide
  • Threading Programming Guide
  • Memory Management Programming Guide for Core Foundation
  • Notification Programming Topics
  • Objective-C Runtime Programming Guide
  • Table View Programming Guide for iOS
  • View Programming Guide for iOS
  • View Controller Programming Guide for iOS
  • Effective Objective-C 2.0:编写高质量iOS与OS X代码的52个有效方法
  • iOS开发进阶
  • Objective-C高级编程 iOS与OS X多线程和内存管理
  • Pro Objective-C

其他

  • Advanced Mac OS X Programming
  • Functional Reactive Programming on iOS