Grand Central Dispatch Sample

说来惭愧,做 iDev 一年多了,最近才第一次在正式项目中使用 GCD。做个笔记。

Grand Central Dispatch(GCD) 是苹果 iOS 4 推出的任务调度机制,把不同的任务分配给不同的 queue 来处理,非常适合异步任务,支持多核处理器,比 performSelectorInBackground 这种线程调度有更好的处理性能,而且配合 Blocks 使用非常方便。

dispatch_queue_t bgQueue = dispatch_queue_create("im.fann.bgQueue", NULL);
// or dispatch_queue_t bgQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// or dispatch_queue_t bgQueue = dispatch_get_global_queue(0, 0,); for short

dispatch_async(bgQueue, ^{

    ...// load data from server

    dispatch_async(dispatch_get_main_queue, ^{
        // dispatch_get_main_queue get back to the main queue to update UI. You can only change UI in main queue.
        [rootTableView reloadData];
    });
});

非常棒的 GCD 系列教程:

Happy Birthday to my Blog

四年前的今天写了 Hello World!,希望能一直写下去。

Happy Birthday.

iOS 模拟器界面调试小工具

不知道 Xcode 什么时候添加进来的功能,在模拟器 Debug 菜单下选中 Color Blended Layers 可以很方便的查看界面元素排版布局。

Color Blended Layers

BTW, 现在在模拟器可以直接 Command+S 来截图了。

iOS 5 Settings URL scheme

在 iOS 5+ 可以通过 URL scheme 快速打开【设置】及子项。

Settings                prefs:
About                   prefs:root=General&path=About
Accessibility           prefs:root=General&path=ACCESSIBILITY
Airplane Mode On        prefs:root=AIRPLANE_MODE
Auto-Lock               prefs:root=General&path=AUTOLOCK
Brightness              prefs:root=Brightness
Bluetooth               prefs:root=General&path=Bluetooth
Date & Time             prefs:root=General&path=DATE_AND_TIME
FaceTime                prefs:root=FACETIME
General                 prefs:root=General
Keyboard                prefs:root=General&path=Keyboard
iCloud                  prefs:root=CASTLE
iCloud Storage & Backup prefs:root=CASTLE&path=STORAGE_AND_BACKUP
International           prefs:root=General&path=INTERNATIONAL
Location Services       prefs:root=LOCATION_SERVICES
Music                   prefs:root=MUSIC
Music Equalizer         prefs:root=MUSIC&path=EQ
Music Volume Limit      prefs:root=MUSIC&path=VolumeLimit
Network                 prefs:root=General&path=Network
Nike + iPod             prefs:root=NIKE_PLUS_IPOD
Notes                   prefs:root=NOTES
Notification            prefs:root=NOTIFICATIONS_ID
Phone                   prefs:root=Phone
Photos                  prefs:root=Photos
Profile                 prefs:root=General&path=ManagedConfigurationList
Reset                   prefs:root=General&path=Reset
Safari                  prefs:root=Safari
Siri                    prefs:root=General&path=Assistant
Sounds                  prefs:root=Sounds
Software Update         prefs:root=General&path=SOFTWARE_UPDATE_LINK
Store                   prefs:root=STORE
Twitter                 prefs:root=TWITTER
Usage                   prefs:root=General&path=USAGE
VPN                     prefs:root=General&path=Network/VPN
Wallpaper               prefs:root=Wallpaper
Wi-Fi                   prefs:root=WIFI

via Apple Settings App/Preference Shortcuts

Setup Mac Development Environment

  1. System Software Update.
  2. Download and install Xcode, or Command Line Tools for Xcode only if you don’t need Xcode.
  3. Install Homebrew.
  4. Get back your dotfiles if you have.

Python

  1. Use pip instead of easy_install
  2. Use pip to install virtualenv and virtualenvwrapper
# use easy_install to install pip
sudo easy_install pip
# where pip
/usr/local/bin/pip
# virtualenv
sudo pip install virtualenv
# which virtualenv
/usr/local/bin/virtualenv
# virtualenvwrapper
sudo pip install virtualenvwrapper
# virtualenvwrapper will be installed in /usr/local/bin/virtualenvwrapper.sh
# config virtualenvwrapper
mkdir ~/.virtualenvs
# edit .zshrc and add
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

Ruby

Install RVM

# add to .zshrc
[[ -s $HOME/.rvm/scripts/rvm ]] && source $HOME/.rvm/scripts/rvm
# install ruby by rvm
rvm install 1.9.2 && rvm use 1.9.2
rvm rubygems latest

Compile and install SVN 1.7.2 on Mac

Just a note for myself.

  1. Download svn-1.7.2.tar.gz source.
  2. Run ./autogen.sh to check the necessary components to build svn.
  3. ./configure then make and sudo make install.

All commands:

./autogen.sh
./configure --disable-debug --with-ssl --with-zlib=/usr --with-sqlite=/usr --disable-neon-version-check --disable-mod-activation --without-apache-libexecdir --without-berkeley-db --with-neon=/usr/local/Cellar/neon/0.29.6/
make
sudo make install

加速 Xcode 文档搜索

Xcode 的文档搜索速度实在是不给力,因为 Xcode 是实时的索引所有 Doc Sets 来查找。解决方法:

  1. 更换 SSD,一劳永逸,更能带来编译速度的极大提升。
  2. 第三方文档搜索工具,比如 Ingredients、AppKiDo,缺点是没法和 Xcode 完美结合,比如 Option+Click 快速查找。
  3. 修改 Find Options 来减少一些索引,只做 iOS 就没必要选 Mac 的 Doc Sets. 另外 Match Type 选 Prefix 也会快很多。可以参考下面这个 Find Options 设置。

speedup Xcode doc search

感谢 @jjgod 分享的小技巧。

[self review:2011];

2011

2011 年度个人总结。

工作

一整年的 iOS 开发,相对于去年入门时 Rookie 最大的成长是教训,经验和信心。

有那么一次,客户端测试时候频繁崩溃却毫无头绪,那个上火啊,甚至晚上做梦都在 Debug,有一晚上还真在梦中解决了一个问题。没有教训就没有记忆,这也是为啥后来我偏执的强迫症般的抓内存泄漏找潜在崩溃。经验就是由这么一堆教训堆积出来的,一次次的总结然后下一次避免,这不就是成长么?

如果一年前跟我说我们的竞争对手如此之多,甚至还有上市公司,我绝对没有信心去继续这个项目。不是说我太消极,而是对于这个市场的一无所知。不是都说恐惧源自于无知么。这一年下来,随着技术上的完善,产品的坚持,市场的更加熟悉,我们现在是信心满满的面对每个竞争对手。

本来四季度时想跟进学一下服务端开发,阴差阳错的给错过了,算是今年的一个遗憾吧。来年一定要跟进。

没来得及搞服务端,腾出时间整理了内部 iOS 编码规范和通用库,这个过程正好把前面一年的开发梳理了一下,收获很大。以后要坚持定期的回头梳理。

产品细节上这一年有不少进步,但是整体把控还不行,产品这一块是个长期,坚持。

生活

圣诞节时跟远大萌感慨说老了,平安夜都没有出去 High。其实是平静了,我们会周末窝家里做饭,给爸妈打电话唠叨,我觉得挺好。

今年最高兴的就是在家里需要的时候我和妞妞有能力帮一把,不让爸妈那么累,那么苦,尽管力量还很小。我一直认为家是生活的中心,如果连家里人的生活都无力改善,那你改变世界的理想都是扯淡。

大年初六我和妞妞订婚了。这一年我们有生气,有争吵,但我们比以往更爱对方。两个人在一起不容易,很感谢妞妞对我的理解、支持和包容。

这一年控制着没有继续长胖,不过也没有瘦,身体没有什么大毛病,但明显身体素质比以前差了不少,得加强一下锻炼,向罗胖子学习。


2012

工作

  1. 加强 iOS 开发,尤其是新技术的学习和整理,比如 ARC。
  2. 尝试 iPad 开发,这可不是简单的界面放大,整个用户交互都需要重新学习理解。
  3. 服务端开发,至少是应用级别要跟上,已经落户一步,不能拖太久。
  4. 继续加强产品能力,尤其是整体把握。

生活

  1. 完婚。
  2. 给家里更多的帮助,让爸妈轻松一点。
  3. 希望今年能有一次旅游,厦门?

最后来张截图

2011

[MFMailComposeViewController canSendMail] issue

发现 MFMailComposeViewController 一个挺奇怪的问题,代码一:

if ([MFMailComposeViewController canSendMail]) {
    MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
    [mailComposer setSubject:@"Mail"];
    //...
    [self presentModalViewController:mailComposer animated:YES];
    [mailComposer release];
}

如果设备没有设置 Mail,那么该操作不会有任何反应。不会有弹窗出现。

代码二:

MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc] init];
if (![MFMailComposeViewController canSendMail]) {
    return;
}
//...

代码二这种情况下如果没有设置 Mail,会有系统弹窗提示 “无邮件账户”。

How To Make Your iPhone’s Home Button More Responsive