<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[A Bite of Cocoa]]></title>
  <link href="http://lldong.github.com/atom.xml" rel="self"/>
  <link href="http://lldong.github.com/"/>
  <updated>2013-04-28T21:13:47+08:00</updated>
  <id>http://lldong.github.com/</id>
  <author>
    <name><![CDATA[lldong]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Git and Github Secrets 筆記]]></title>
    <link href="http://lldong.github.com/blog/2012/11/07/git-and-github-secrets/"/>
    <updated>2012-11-07T03:44:00+08:00</updated>
    <id>http://lldong.github.com/blog/2012/11/07/git-and-github-secrets</id>
    <content type="html"><![CDATA[<p>&#8220;Git and Github Secrets&#8221;是Github的<a href="https://github.com/benhoman">Ben Homan</a>在Aloha Ruby Conf 2012上的一個<a href="http://confreaks.com/videos/1229-aloharuby2012-git-and-github-secrets">演講</a>, 介紹了一些Github和Git鮮爲人知的技巧，下面是這個演講部分內容的筆記：</p>

<h2>Github</h2>

<ul>
<li><p>在某個commit頁面的URL後面加上<code>.patch</code>或者<code>.diff</code>後綴可以查看該commit的diff輸出結果，如果在加上<code>?w=1</code>後綴可以忽略<code>whitespace</code></p></li>
<li><p>每個Github的repository實際上可以當作svn repository去使用，Github會自動做操作的映射，比如：<code>svn checkout github.com/homan/boom</code></p></li>
<li><p><code>clone</code>一個項目是可以忽略地址裏面的.git後綴</p></li>
<li><p>Github有一個網址縮略服務，git.io，不過只能縮略github.com上的網址</p></li>
<li><p>每一個gist其實也是一個git repository (git.io/mini)</p></li>
<li><p>Github網頁上可以使用一些快捷鍵盤，<code>t</code>可以調出類似Command-T的文件跳轉功能，<code>s</code>可以進入搜索，<code>?</code>會顯示快捷鍵幫助提示</p></li>
<li><p>Github會自動將一些值轉爲URL，比如：commit的SHA值，issue編號，user/repo@SHA的格式</p></li>
<li><p><code>closes/closed/close #1</code> 或 <code>fixs/fixed/fix #1</code> comment中的字眼會被自動識別並關閉對應的issue</p></li>
<li><p>在commit history頁面的URL後面加上 <code>?author=USER_NAME</code> 或者 <code>?author=EMAIL</code>可以查看某人的具體提交記錄</p></li>
<li><p>Github會自動緩存外鏈圖片</p></li>
<li><p>支持<code>:EMOJI_CODE:</code>方式輸入emoji表情，<a href="http://www.emoji-cheat-sheet.com/">這裏</a>有所有支持表情的代碼</p></li>
<li><p>代碼頁面的URL可以用<code>#L12-20</code>的方式標記需要高亮12-20行。</p></li>
<li><p>compare頁面可以用<code>github.com/user/repo/compare/{range}</code>的URL格式顯示對比的範圍支持類似<code>master@{1.day.ago}…master</code>這樣靈活的格式。</p></li>
</ul>


<h2>Git</h2>

<ul>
<li><p><code>--allow-empty</code>允許空白的commit</p></li>
<li><p><code>git add -p</code>可以讓你手動選擇那些需要add的內容，<a href="http://johnkary.net/git-add-p-the-most-powerful-git-feature-youre-not-using-yet/">這篇文章</a>有詳細介紹。</p></li>
<li><p><code>git show :/QUERY</code>可以在commit記錄中搜索特定字眼</p></li>
<li><p>和Bash中的<code>cd -</code>命令類似<code>git checkout -</code>可以快速checkout上個分支</p></li>
<li><p><code>git  branch --no-merged/--merged</code>可以查看已經merge或沒merge到當前分支的branch</p></li>
<li><p><code>git branch --contains SHA</code>快速切換到包含制定commit的branch</p></li>
<li><p><code>git checkout BRANCH -- path/to/file.rb</code>將BRANCH中的file.rb文件拷貝到當前branch中，無需切換</p></li>
<li><p><code>git log branchA^branchB</code>顯示只在A分支而不在B分支的commits</p></li>
<li><p><code>git fsck --lost-found</code>查看沒有被引用的commit，可以找回被誤刪的commit</p></li>
<li><p><code>git diff HEAD^ --stat</code>顯示兩次commit間repository的狀態變化</p></li>
<li><p><code>git blame -w</code>查看誰修改了哪一行代碼，<code>-w</code>選項會忽略whitespace</p></li>
<li><p><code>git blame -M</code>如上，不過會體現同個commit中的代碼行移動</p></li>
<li><p><code>git blame -C/-CC/-CCC</code>如上，不過會體現同個commit中代碼行在文件之間移動，<code>-CC</code>選項還會從創建該文件的commit中查找，<code>-CCC</code>選項會從所有commit的其它文件中查找。</p></li>
<li><p><code>git config remotes.mygroup 'remote1 remote2'</code>對幾個分支創建一個group，從而可以批量操作幾個分支</p></li>
<li><p><code>git diff HEAD^ --word-diff</code>顯示逐詞的diff</p></li>
<li><p><code>git config --global rerere.enable 1</code>記錄之前解決merge衝突的操作，並在下一次出現衝突時自動處理</p></li>
<li><p><code>git-amend</code>或者<code>git commit --amend -C HEAD</code>修改某次commit記錄</p></li>
<li><p><code>git reset --soft HEAD^</code>重置到上個commit，但是已有的commit不會丟失</p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cocoa 漢字轉拼音最簡單的方法]]></title>
    <link href="http://lldong.github.com/blog/2012/11/06/hanzi-to-pinyin/"/>
    <updated>2012-11-06T16:14:00+08:00</updated>
    <id>http://lldong.github.com/blog/2012/11/06/hanzi-to-pinyin</id>
    <content type="html"><![CDATA[<p>在開發中文應用的過程中，有時會與到需要將漢字轉爲拼音的需求，在網上搜索一下會發現不少這樣的庫，這些庫的實現多數是通過查表的方式，而且實現比較複雜，使用和維護不是很方便。其實，作爲幸福的Cocoa開發者，這項功能已經再Core Foundation的類庫中提供了，並且可以處理多種文字的轉譯，廢話少說，下面是代碼：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">NSMutableString</span> <span class="o">*</span><span class="n">string</span> <span class="o">=</span> <span class="p">[</span><span class="s">@&quot;你好&quot;</span> <span class="n">mutableCopy</span><span class="p">];</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Before: %@&quot;</span><span class="p">,</span> <span class="n">string</span><span class="p">);</span> <span class="c1">// Before: 你好</span>
</span><span class='line'><span class="n">CFStringTransform</span><span class="p">((</span><span class="n">__bridge</span> <span class="n">CFMutableStringRef</span><span class="p">)</span><span class="n">string</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">kCFStringTransformMandarinLatin</span><span class="p">,</span> <span class="n">NO</span><span class="p">);</span>
</span><span class='line'><span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;After: %@&quot;</span><span class="p">,</span> <span class="n">string</span><span class="p">);</span> <span class="c1">// After: nǐ hǎo   </span>
</span></code></pre></td></tr></table></div></figure>


<p>這裏使用的是CFStringTransform這個函數，函數的簽名如下：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">Boolean</span> <span class="n">CFStringTransform</span> <span class="p">(</span>
</span><span class='line'>   <span class="n">CFMutableStringRef</span> <span class="n">string</span><span class="p">,</span>
</span><span class='line'>   <span class="n">CFRange</span> <span class="o">*</span><span class="n">range</span><span class="p">,</span>
</span><span class='line'>   <span class="n">CFStringRef</span> <span class="n">transform</span><span class="p">,</span>
</span><span class='line'>   <span class="n">Boolean</span> <span class="n">reverse</span>
</span><span class='line'><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>四個參數分別代表：待轉換的字符串(<code>string</code>)，轉換的範圍(<code>range</code>)，轉換的選項(<code>transform</code>)，是否逆向轉換(<code>reverse</code>)。漢字轉拼音的關鍵就在於第三個參數<code>transform</code>常量，我們這裏使用的是<code>kCFStringTransformMandarinLatin</code>這個選項，對於處理其它的語言可以使用對應的選項，文檔中有所有選項的說明。</p>

<p>你會發現上面的轉換結果是帶拼音聲調標記的，但是有時候我們並不需要音標，對於這樣的需求，我們可以用另一個<code>transform</code>選項<code>kCFStringTransformStripDiacritics</code>進行處理：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'>   <span class="n">NSMutableString</span> <span class="o">*</span><span class="n">string</span> <span class="o">=</span> <span class="p">[</span><span class="s">@&quot;你好&quot;</span> <span class="n">mutableCopy</span><span class="p">];</span>
</span><span class='line'>   <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Before: %@&quot;</span><span class="p">,</span> <span class="n">string</span><span class="p">);</span> <span class="c1">// Before: 你好</span>
</span><span class='line'>   <span class="n">CFStringTransform</span><span class="p">((</span><span class="n">__bridge</span> <span class="n">CFMutableStringRef</span><span class="p">)</span><span class="n">string</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">kCFStringTransformMandarinLatin</span><span class="p">,</span> <span class="n">NO</span><span class="p">);</span>
</span><span class='line'>   <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;After: %@&quot;</span><span class="p">,</span> <span class="n">string</span><span class="p">);</span>  <span class="c1">// After: nǐ hǎo  </span>
</span><span class='line'>   <span class="n">CFStringTransform</span><span class="p">((</span><span class="n">__bridge</span> <span class="n">CFMutableStringRef</span><span class="p">)</span><span class="n">string</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">kCFStringTransformStripDiacritics</span><span class="p">,</span> <span class="n">NO</span><span class="p">);</span>
</span><span class='line'>   <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;Striped: %@&quot;</span><span class="p">,</span> <span class="n">string</span><span class="p">);</span> <span class="c1">// Striped: ni hao</span>
</span></code></pre></td></tr></table></div></figure>


<h3>總結</h3>

<p>Cocoa類庫經過20幾年的發展，已經是一個十分成熟的類庫，你總會發現它能用很少代碼實現意想不到的功能，所以有時候不要急於發明輪子，Cocoa的文檔中或許就已經有優雅的解決辦法了。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[UIKit收起鍵盤最好的方法]]></title>
    <link href="http://lldong.github.com/blog/2012/11/02/dissmiss-keyboard/"/>
    <updated>2012-11-02T17:04:00+08:00</updated>
    <id>http://lldong.github.com/blog/2012/11/02/dissmiss-keyboard</id>
    <content type="html"><![CDATA[<p>在開發iOS程序時經常需要控制鍵盤的收起，一般我們都是通過<code>UITextField</code>的彈出鍵盤和<code>-resignFirstResponder</code>去觸發，但是這樣做有個缺點，就是需要用一個實例變量去記住當前的TextField，這种給對象增加一個狀態（實例變量）的方法顯然不是很優雅。由於整個Cocoa的UI框架都中使用了響應者鍊（<code>responder chain</code>）的設計模式來實現事件傳遞，它在AppKit中是很強大的工具，但在iOS中卻相對少用，不過我們這裏就是利用它來現收方便地收起鍵盤。在<code>NSApplication</code>中有個<code>- (BOOL)sendAction:(SEL)anAction to:(id)aTarget from:(id)sender</code>方法，用來發送一個action消息到某個target，但是這個方法如果target爲nil的話，那麼這個消息會從<code>firstResponder</code>開始沿着<code>responder chain</code>傳遞，直到有對象響應改消息爲止（Mac上的Menubar和Toolbar就是利用這個原理實現的，隨着界面焦點的不同其選項的狀態也會變化，而且不需要寫很複雜的邏輯去處理）。我們這裏要用的是<code>UIApplication</code>對應的方法<code>- (BOOL)sendAction:(SEL)action to:(id)target from:(id)sender forEvent:(UIEvent *)event</code>，然後，當你需要收起鍵盤的時候就只要這樣：</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="p">[[</span><span class="n">UIApplication</span> <span class="n">sharedApplication</span><span class="p">]</span> <span class="nl">sendAction:</span><span class="k">@selector</span><span class="p">(</span><span class="n">resignFirstResponder</span><span class="p">)</span>
</span><span class='line'>                                           <span class="nl">to:</span><span class="nb">nil</span>
</span><span class='line'>                                         <span class="nl">from:</span><span class="nb">nil</span>
</span><span class='line'>                                     <span class="nl">forEvent:</span><span class="nb">nil</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p>由於不需要依賴實例變量，所以可以直接封裝到NSViewController的一個Category裏面去，以後子類就可以方便地通過類似<code>-dismissKeyboard</code>的方法收起鍵盤。</p>

<p><strong>Edit:</strong> 好吧，其实还有更简单的方法，<code>-[UIView endEditing]</code> 可以让该view或者该view的子view中的textfield结束编辑状态。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[你應該知道的幾個Xcode插件]]></title>
    <link href="http://lldong.github.com/blog/2012/10/06/xcode-plugins-you-should-know/"/>
    <updated>2012-10-06T15:38:00+08:00</updated>
    <id>http://lldong.github.com/blog/2012/10/06/xcode-plugins-you-should-know</id>
    <content type="html"><![CDATA[<h2><a href="http://codepilot.cc/">Code Pilot 2</a></h2>

<p>Xcode上的Command-T，讓你快速跳轉到某個文件或某個符號</p>

<h2><a href="https://github.com/JugglerShu/XVim">XVim</a></h2>

<p>讓Xcode使用Vim的鍵綁定，Vim党必備</p>

<h2><a href="http://injectionforxcode.com/">Injection for Xcode</a></h2>

<p>調試利器，直接將修改后的代碼注入到正運行的程序中，無需重新Build &amp; Run（其實這功能之前Xcode 3是有的&#8230;）</p>

<h2><a href="http://www.kevincallahan.org/software/accessorizer.html">Accessorizer</a></h2>

<p>根據Xcode中選中的文本自動生成代碼，提供多種模板和豐富的設置</p>

<h2><a href="https://github.com/omz/ColorSense-for-Xcode">ColorSense-for-Xcode</a></h2>

<p>直接在代碼中顯示NSColor/UIColor的顏色，並可直接使用調色板輸入顏色代碼</p>

<h2><a href="https://github.com/omz/MiniXcode">MiniXcode</a></h2>

<p>讓Xcode在隱藏Toolbar后顯示Schema選擇菜單，適合再小屏幕上使用Xcode</p>

<h2><a href="https://github.com/omz/Dash-Plugin-for-Xcode">Dash-Plugin-for-Xcode</a></h2>

<p>在Dash中查看Xcode里當前文本的相關文檔，提供快捷鍵</p>

<h2><a href="https://github.com/CocoaPods/CocoaPods">CocoaPods</a></h2>

<p>管理和使用各種第三方庫的命令行工具，誰用誰知道</p>

<h2>[KSImageNamed-Xcode][https://github.com/ksuther/KSImageNamed-Xcode]</h2>

<h2><a href="https://github.com/davekeck/Xcode-4-Fixins">Xcode-4-Fixins</a></h2>

<h2><a href="https://github.com/jaydee3/JDListInstalledPlugins">JDListInstalledPlugins</a></h2>

<h2><a href="https://github.com/square/PonyDebugger">PonnyDebugger</a></h2>

<h2><a href="https://github.com/pablomarx/PonyDebugger">PonnyDebugger-F-Script</a></h2>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Xcode 4.3 MacRuby compatible problem workaround]]></title>
    <link href="http://lldong.github.com/blog/2012/03/05/xcode-4-dot-3-macruby-compatible-problem-workaround/"/>
    <updated>2012-03-05T23:57:00+08:00</updated>
    <id>http://lldong.github.com/blog/2012/03/05/xcode-4-dot-3-macruby-compatible-problem-workaround</id>
    <content type="html"><![CDATA[<p>Since Xcode 4.3 has became a standalone app, it&#8217;s no longer installed in the <code>/Developer</code> directory. This cause the MacRuby project template disappear from Xcode 4.3. After some digging in the MacRuby-devel mailing list, I found some workaround to this problem:</p>

<p>First, you need to move the MacRuby template files to the user&#8217;s shared folder:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'>
</span><span class='line'>mkdir -p ~/Library/Developer/Xcode/Templates/Application
</span><span class='line'><span class="nb">cd</span> ~/Library/Developer/Xcode/Templates/Application
</span><span class='line'>cp -R /Developer/Library/Xcode/Templates/* .
</span></code></pre></td></tr></table></div></figure>


<p>After the previous step, you should find the MacRuby project templete in Xcode, but, the Interface Builder support is still broken. To solve this problem, you need to tell Xcode where the <code>rb_nibtool</code> is:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="nb">cd</span> /Applications/Xcode.app/Contents/Developer/Tools
</span><span class='line'>sudo ln -s /Library/Frameworks/MacRuby.framework/Versions/Current/usr/bin/rb_nibtool
</span></code></pre></td></tr></table></div></figure>


<p>Then, restart Xcode, and the <code>rb_nibtool</code> should works again now. But this workaround exposes a serious bug: you create a symlink in the Xcode bundle without breaking the code sign, which means you make a signed app to run unsigned code!</p>

<p>Edit:Thanks @Jonathan for pointing out a typo in the second code snippet, the missing <code>/</code> will cause Xcode to crash.</p>

<p>P.S. If you remove the <code>/Developer</code> directory after install Xcode 4.3, you should install the <a href="https://developer.apple.com/downloads/index.action">Command Line Tools</a> from Apple. Whithout the tool-chain, you will failed to compile from source in command line. And you should also run <code>sudo xcode-select -switch /Applications/Xcode.app/Contents/Developer</code> to tell <code>xcodebuile</code> about the new path, or building Xcode project from command line will fail too.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Objective-C Runtime]]></title>
    <link href="http://lldong.github.com/blog/2012/03/05/objective-c-runtime/"/>
    <updated>2012-03-05T23:26:00+08:00</updated>
    <id>http://lldong.github.com/blog/2012/03/05/objective-c-runtime</id>
    <content type="html"><![CDATA[<p>我之前在<a href="http://techparty.org/">珠三角技术沙龙</a>上一个关于Objective-C运行时的<a href="http://speakerdeck.com/u/lldong/p/objective-c-runtime">分享</a></p>

<h3>Speaker Deck</h3>

<script async class="speakerdeck-embed" data-id="4f54dc912b27ce002100de53" data-ratio="1.3333333333333333" src="http://lldong.github.com//speakerdeck.com/assets/embed.js"></script>


<h3>Slideshare</h3>

<div style="width:425px" id="__ss_10033272"> <strong style="display:block;margin:12px 0 4px"><a href="http://www.slideshare.net/Michael2008S/objective-runtime" title="Objective runtime" target="_blank">Objective runtime</a></strong> <iframe src="http://www.slideshare.net/slideshow/embed_code/10033272" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe> <div style="padding:5px 0 12px"> View more <a href="http://www.slideshare.net/" target="_blank">presentations</a> from <a href="http://www.slideshare.net/Michael2008S" target="_blank">Michael2008S</a> </div> </div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Some Useful Bitwise Operations]]></title>
    <link href="http://lldong.github.com/blog/2011/12/30/some-useful-bitwise-operations/"/>
    <updated>2011-12-30T22:01:00+08:00</updated>
    <id>http://lldong.github.com/blog/2011/12/30/some-useful-bitwise-operations</id>
    <content type="html"><![CDATA[<ul>
<li><p>Check if the integer is even</p>

<p>  (x &amp; 1) == 0</p></li>
<li><p>Check if n-th bit is set</p>

<p>  x &amp; (1 &lt;&lt; n) == 0</p></li>
<li><p>Set the n-th bit</p>

<p>  x | (1 &lt;&lt; n)</p></li>
<li><p>Unset the n-th bit</p>

<p>  x &amp; ~(1 &lt;&lt; n)</p></li>
<li><p>Toggle the n-th bit</p>

<p>  x ^ (1 &lt;&lt; n)</p></li>
<li><p>Isolate the rightmost 1-bit</p>

<p>  x &amp; (-x)</p></li>
<li><p>Turn off the rightmost 1-bit</p>

<p>  x &amp; (x – 1)</p></li>
<li><p>Right propagate the rightmost 1-bit</p>

<p>  x | (x - 1)</p></li>
<li><p>Isolate the rightmost 0-bit</p>

<p>  ~x &amp; (x + 1)</p></li>
<li><p>Turn on the rightmost 0-bit</p>

<p>  x | (x + 1)</p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Blocks]]></title>
    <link href="http://lldong.github.com/blog/2011/12/30/blocks/"/>
    <updated>2011-12-30T21:55:00+08:00</updated>
    <id>http://lldong.github.com/blog/2011/12/30/blocks</id>
    <content type="html"><![CDATA[<p>从Mac OS X 10.6以及iOS 4开始，苹果在GCC和Clang编译器中为C语言引入了一个新扩展:<em>Blocks</em>，使得程序员可以在C、Objective-C、C++和Objective-C中使用闭包。<em>Blocks</em>有点像函数，但是它可以在其它函数或方法中进行声明和定义，同时它还是匿名的（匿名函数），并可以捕获其所在作用域中的变量（闭包特性)。</p>

<h2><em>Blocks</em>的语法</h2>

<p><em>Blocks</em>和C语言中的函数指针有点类似，如果你了解函数指针的话你会发现<em>Blocks</em>的会很容易掌握。下面分别是一个C函数指针和一个<em>Blocks</em>的声明：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">foo</span><span class="p">)(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="p">(</span><span class="o">^</span><span class="n">foo</span><span class="p">)(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>它们都是接受两个<code>int</code>类型的参数并且返回一个<code>int</code>值，唯一的区别就是函数指针声明中的<code>*</code>变成了<code>^</code>。根据苹果的说法，之所以选用<code>^</code>是因为它是C++中唯一不能被重载的运算符号。此外，由于两者的声明都过于烦琐，所以你可以像C中一样利用<code>typedef</code>为该类型起一个别名，方便你在代码中使用：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">typedef</span> <span class="kt">int</span> <span class="p">(</span><span class="o">*</span><span class="n">Fp</span><span class="p">)(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">);</span>
</span><span class='line'><span class="n">Fp</span> <span class="n">foo</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="k">typedef</span> <span class="kt">int</span> <span class="p">(</span><span class="o">^</span><span class="n">Block</span><span class="p">)(</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="p">);</span>
</span><span class='line'><span class="n">Block</span> <span class="n">foo</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>


<p>接下来看看如何定义一个<em>Block</em>：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">Block</span> <span class="n">sum</span> <span class="o">=</span> <span class="kt">int</span> <span class="o">^</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">x</span>   <span class="n">y</span><span class="p">;</span> <span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>


<p>其中<code>^</code>标志着这是一个<em>Block</em>定义，在它前面是其返回值的类型，括号中是其接受的各个参数，而<em>Block</em>的主体则位于<code>{}</code>中。由于编译器可以自动推断<em>Block</em>的返回类型，所以<code>^</code>前面的返回类型可以略去不写，同时，如果该<em>Block</em>没有接受任何参数，括号的部分也可以省略；</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">Block</span> <span class="n">sum</span> <span class="o">=</span> <span class="o">^</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">x</span>   <span class="n">y</span><span class="p">;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="p">(</span><span class="o">^</span><span class="n">bar</span><span class="p">)(</span><span class="kt">void</span><span class="p">)</span> <span class="o">=</span> <span class="o">^</span> <span class="p">{</span> <span class="n">printf</span><span class="p">(</span><span class="s">&quot;Hello World!</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">);</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2><em>Blocks</em>的基本用法</h2>

<p>执行一个<em>Block</em>和调用一个C函数一样</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="n">sum</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">);</span>      <span class="c1">// 输出 5</span>
</span></code></pre></td></tr></table></div></figure>


<p>此外，在Objective-C中一个<em>Block</em>同时也是一个对象，它也有一个isa指针指向它的类对象。这意味着你能够对它发送诸如<code>-copy</code>、<code>-release</code>和<code>retain</code>等消息。</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="p">[</span><span class="n">sum</span> <span class="n">copy</span><span class="p">];</span>
</span></code></pre></td></tr></table></div></figure>


<p><em>Blocks</em>具有闭包的特性，所以可以用它来捕获其所在作用域中的变量：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="kt">void</span> <span class="nf">testBlock</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">int</span> <span class="p">(</span><span class="o">^</span><span class="n">aBlock</span><span class="p">)(</span><span class="kt">void</span><span class="p">)</span> <span class="o">=</span> <span class="o">^</span> <span class="p">{</span> <span class="k">return</span> <span class="n">a</span>   <span class="n">b</span><span class="p">;</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">aBlock</span><span class="p">());</span>   <span class="c1">// 输出 3</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">a</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">aBlock</span><span class="p">());</span>   <span class="c1">// 还是输出 3</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>需要注意的是，两次输出的值都为3，即使在第二次输出前我们已经将a的值赋为0。这是因为在定义<code>aBlock</code>时编译器已经对<code>a</code>和<code>b</code>的值作了一个<code>const</code>拷贝（你不能在<code>aBlock</code>中修改a的值）并保存，导致后续外部对<code>a</code>的修改没有影响到<code>aBlock</code>的执行结果。如果想在<code>aBlock</code>中通过引用访问<code>a</code>或者修改<code>a</code>的值，你需要在<code>a</code>的声明前加上一个限定词<code>__block</code>：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="kt">void</span> <span class="nf">testBlock</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">__block</span> <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="kt">int</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>    <span class="kt">int</span> <span class="p">(</span><span class="o">^</span><span class="n">aBlock</span><span class="p">)(</span><span class="kt">void</span><span class="p">)</span> <span class="o">=</span> <span class="o">^</span> <span class="p">{</span> <span class="k">return</span> <span class="n">a</span>   <span class="n">b</span><span class="p">;</span> <span class="p">};</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">a</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>    <span class="n">printf</span><span class="p">(</span><span class="s">&quot;%d</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span> <span class="n">aBlock</span><span class="p">());</span>   <span class="c1">// 输出 2</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>这样，使用该限定词的变量会通过引用的方式传入<em>Block</em>，使得它的值可以在<em>Block</em>执行后被修改。这样的变量通常是保存在栈中的，但是如果引用该变量的<em>Block</em>被拷贝，它也会随之被拷贝到堆中。</p>

<h2><em>Blocks</em>的内存管理</h2>

<p>编译后<em>Block</em>中代码的存储和加载方式其实和普通的函数一样，但是它还需要额外的空间去保存其所捕获的变量，也就是说，<em>Block</em>中所引用的变量需要被拷贝到一块其私有的内存中去。当你声明定义了一个<em>Block</em>时，它的这块私有内存空间是分配在栈中。所以默认情况下当定义<em>Block</em>的方法或函数返回后这块内存也会随之失效。所以当你需要返回一个<em>Block</em>时，你需要显式地用<code>Block_copy()</code>（如果该<em>Block</em>已经在堆中，它的<code>retain count</code>将会加1）将拷贝到堆中。由于在Objective-C中<em>Block</em>也是一个对象，所以你也可以对它发送<code>-copy</code>消息来达到同样地效果。既然有一个拷贝的过程，那么当你使用完毕的时候也需要调用用<code>Block_release()</code>进行对应的释放操作，同理，在Objective-C中也可对其发送<code>-release</code>消息。需要注意的一点是下面这种情况也会导致一个<em>Block</em>的私有存储空间失效：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="k">typedef</span> <span class="kt">void</span><span class="p">(</span><span class="o">^</span><span class="n">Block</span><span class="p">)(</span><span class="kt">void</span><span class="p">);</span>
</span><span class='line'><span class="kt">void</span> <span class="nf">foo</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">Block</span> <span class="n">aBlock</span><span class="p">;</span>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="n">condition</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">aBlock</span> <span class="o">=</span> <span class="o">^</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">aBlock</span> <span class="o">=</span> <span class="o">^</span> <span class="p">{</span> <span class="p">...</span> <span class="p">};</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>    <span class="p">...</span>
</span><span class='line'>    <span class="c1">// 此时aBlock已经指向一块无效的内存</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>上面讲到在Objective-C中<code>Block</code>也是一个对象，所以你可以对其发送<code>-copy</code>、<code>-retain</code>、<code>-copy</code>甚至<code>-autorelease</code>等消息进行对应的内存管理。但是在Objective-C中<em>Block</em>有一点不同，它会对所引用的<code>NSObject</code>对象自动进行<code>retain</code>操作（当<em>Block</em>销毁时这些对象也会被<code>release</code>），包括其它<em>Block</em>。所以你也可以利用这个特性使得一个非继承自<code>NSObject</code>的对象被自动<code>retain</code>，方法就是在该对象的声明加上<code>__attribute__((NSObject))</code>。 需要注意的是，如果你引用的是一个实例变量，它会直接对<code>self</code>进行<code>retain</code>，这有时候有可能会产生一个引用环（两个或以上的对象之间直接或间接地互相引用）并导致内存泄露。解决的方法是：当需要在<em>Block</em>中访问实例变量的时候，创建一个指向<code>self</code>的指针，并对其使用<code>__block</code>修饰符，这样<code>self</code>不会被自动<code>retain</code>：</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='objc'><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">foo</span> <span class="p">{</span>
</span><span class='line'>    <span class="n">__block</span> <span class="kt">id</span> <span class="n">blockSelf</span> <span class="o">=</span> <span class="n">self</span><span class="p">;</span>
</span><span class='line'>    <span class="o">^</span> <span class="p">{</span>
</span><span class='line'>        <span class="n">blockSelf</span><span class="o">-&gt;</span><span class="n">bar</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>因为使用<code>__block</code>修饰符的对象指针的值在<em>Block</em>中是可以被修改的，如果<em>Block</em>自动<code>retain</code>该指针指向的对象，一旦其指针值被修改时应该怎么办呢？而苹果的做法就是干脆不自动<code>retain</code>它。</p>

<p>在Objective-C中还要注意，虽然<em>Block</em>对象可以接受<code>-retain</code>消息，但是对于一个存在于栈中的<em>Block</em>发送该消息是没有效果的。所以，当你要将<em>Blocks</em>对象保存到字典或数组中去之前，需要先执行相应的拷贝操作（因为NSArray或NSDictionary之类容器会自动<code>retain</code>存入的对象）。同理，对一个已经拷贝到堆中的<em>Block</em>发送<code>-copy</code>消息也是不会真正执行拷贝，只是将其引用计数加1，这也意味着拷贝一个<em>Block</em>和重新创建一个一样的<em>Block</em>是不一样的，通过拷贝得到的<em>Block</em>会共享所有声明为<code>__block</code>的变量，所以如果你想要一个全新的<em>Block</em>，你需要重新创建一次。</p>

<h2>总结</h2>

<p><em>Blocks</em>是非常好用的工具，其闭包特性可以让代码更为简洁，比如在使用GCD这类需要指定回调的API的时候（不过使用GCD并不非要用<em>Blocks</em>）。Apple在Cocoa框架中已经加入了很多使用<em>Blocks</em>的API，你也可以在已有API的基础上进行封装使其支持<em>Blocks</em>（比如<a href="https://github.com/zwaldowski/BlocksKit">BlocksKit</a>)，方便使用。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Solarized]]></title>
    <link href="http://lldong.github.com/blog/2011/11/12/solarized/"/>
    <updated>2011-11-12T19:27:00+08:00</updated>
    <id>http://lldong.github.com/blog/2011/11/12/solarized</id>
    <content type="html"><![CDATA[<p><a href="http://ethanschoonover.com/solarized"><em>Solarized</em></a>是一个专门为命令行和GUI程序而设计的16色调色盘(8种单调色和8种强调色)，是我目前见到过最棒的配色方案。它依照精确的<a href="http://en.wikipedia.org/wiki/Lab_color_space">CIELAB</a>亮度关系和一组基于<a href="http://en.wikipedia.org/wiki/Color_wheel">色环</a>关系优化的色度而设计，并且经过在各种不同校准情况和光照条件下显示器的实际测试。其精心的设计使得在使用不同背景(深色或浅色)，不同的字体以及不同选中情况下都能得到最佳的效果。</p>

<p><img src="https://public.sn2.livefilestore.com/y1p2SE8pcc7shwK3zJeW8MDN7ODmkqvfziqJWdPFrPPl0Ty_aT6mQkvkJ1Ki9zWXabVmDSFdE4XSo-QdFkRHvZS9g/solarized-palette.png" alt="" /></p>

<p><em>Solarized</em>同时还提供了一些主流编辑器和终端的色彩主题配置文件，可以到其<a href="http://ethanschoonover.com/solarized">官方网站</a>或者<a href="https://github.com/altercation/solarized">GitHub主页</a>上下载。目前我在Xcode、iTerm2、MacVim、TestMate甚至这个Blog的代码高亮都使用了这款配色，效果十分不错，赶快试一下吧！</p>

<p><img src="https://public.sn2.livefilestore.com/y1p2SE8pcc7shxaSYKbLs_kNLEryaDXoFMJYf6ZkozZaj2btjsA8Bp1RyNoMj7gCO8quxFRAw4FiGYSmC6gAURgHw/solarized-vim.png" alt="" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[retainCount 的那些事情]]></title>
    <link href="http://lldong.github.com/blog/2011/10/20/retain-count/"/>
    <updated>2011-10-20T21:11:00+08:00</updated>
    <id>http://lldong.github.com/blog/2011/10/20/retain-count</id>
    <content type="html"><![CDATA[<p>Objective-C是通过引用计数的方式进行内存管理的，关于这种机制常听到这样一种说法：
“当一个对象的的引用计数值减少到0时，它就会被dealloc”，这种说法看似有理，其实却是错的，因为一个对象的引用计数值永远不会为0！下面将从几个方面解释其原因：</p>

<p>获取一个对象的引用计数的方式一般是通过<code>-retainCount</code>方法，那么这个方法可能返回0吗？答案是否定的，因为如果引用计数为零时对象就会被销毁，那么对其发送<code>-retainCount</code>消息就等同于访问一块被释放的内存，这种行为是未定义的，所以一个正常对象的<code>-retainCount</code>方法不会返回0。（对nil对象发送<code>-retainCount</code>方法返回0情况，其实是objc_msgSend()中对为nil的target做了短路处理，该方法实际并没有被执行）</p>

<p>再从实现的角度看，一个引用计数为1的对象如果收到<code>-release</code>消息就应该被释放了，此时不应再对引用计数进行减1的操作，因为这种这个操作根本就是多余的，是在浪费CPU资源。</p>

<p>下面是GNUStep中NSObject的实现方式（经过简化）：</p>

<pre><code>- (oneway void) release
{
  if (NSDecrementExtraRefCountWasZero(self)) 
  {
      [self dealloc];
  }
}

- (id) retain
{
  NSIncrementExtraRefCount(self);
  return self;
}

- (NSUInteger) retainCount
{
  return NSExtraRefCount(self) + 1;
}
</code></pre>

<p>从上面的代码你会发现<code>-retainCount</code>的返回值其实是1加上一个叫<code>NSExtraRefCount</code>的函数的返回值。那么，这个额外的值是什么呢？原来，当初处于节省内存的目的，<code>NSObject</code>的引用计数值不是保存在对象中，而是保存在一个全局的表里面，这个表里面保存的就是所谓的ExtraRefCount了。但为什么这样能节省内存呢？一种优化的方式是：因为在Objective-C程序中往往会使用很多临时对象（autorelease对象），这些对象的引用计数为1，所以对于这些对象可以不用在表里面标记，并让<code>NSExtraRefCount</code>对查找不到的对象返回0，这样就可以省去一些内存空间了。</p>

<p>最后说明一点，<code>-retainCount</code>不应该作为调试的手段使用，很多原因都会导致其返回值不可靠！</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Retain Release & Autorelease]]></title>
    <link href="http://lldong.github.com/blog/2011/10/16/retain-release-autorelease/"/>
    <updated>2011-10-16T18:06:00+08:00</updated>
    <id>http://lldong.github.com/blog/2011/10/16/retain-release-autorelease</id>
    <content type="html"><![CDATA[<p>在<em>Objective-C</em>中，每一个对象都有一个引用计数值(reference count)。对于新创建的对象其初始值为1，向一个对象发送<code>retain</code>消息会让它的引用计数加1；而向其发送<code>release</code>消息则会对让引用计数减1。如果引用计数爲1時被<code>release</code>，则这个对象会被发送一个<code>dealloc</code>消息进行销毁, 所以也不會存在计数为0的对象。</p>

<p>由于历史的原因，<code>NSObject</code>中默认的引用计数实现并没有将引用计数值保存在对象之中，而是将其保存在一个外部的表中，这样会牺牲一些速度但能节省一些内存。所以<em>Core Foundation</em>以及很多<em>Cocoa</em>中的对象都通过重写<code>retain</code>和<code>release</code>方法将引用计数保存在对象当中以提升速度。</p>

<p>在<em>Lion</em>中苹果重新实现了基于表查找引用计数系统，使得它的速度有显著的提升，但是其基本的思想不变。而新加入的<em>ARC</em>机制在其背后也依然进行了<code>retain</code>和<code>release</code>操作，只不过出于对性能的考虑，编译器会直接调用运行时API进行<code>retain</code>和<code>relese</code>，而不是通过发送消息。</p>

<p>所以一般在<em>Objective-C</em>中如果你<code>alloc</code>，<code>retain</code>或者<code>copy</code>了一个对象，那么你就应该负责<code>release</code>该对象。但这里也有一个问题，就是我们有时无法预知何时释放对象(比如说需要返回一个对象时)，如果过早释放，则对象无法被继续使用，如果没有释放，则可能会造成内存泄露。于是<em>Foundation</em>中提供了<code>NSAutoreleasePool</code>作为解决方案。我们可以通过给对象发送<code>autorelease</code>消息可将对象加入释放池中，从而延迟对象的释放，并在合适的时机对池中对象自动进行释放。</p>

<p><code>autorelease</code>这个方法是在<code>NSObject</code>中实现的，它所做的事情就是调用<code>[NSAutoreleasePool addObject:self]</code>。由于<code>addObject:</code>是一个类方法，所以它需要查找对应的实例去执行操作。 <code>NSAutoreleasePool</code>的实例保存在每个线程中一个特定的栈里，释放池创建时会被压入该栈中，而当销毁时它会被弹出栈。当需要获取当前的释放池时，<code>NSAutoreleasePool</code>就会从当前的栈顶取出释放池进行操作。找到对应的释放池后<code>addObject:</code>方法会将需要自动释放的对象加入到释放池对象的一个列表中。最后，当释放池将被销毁时，池中的每个对象就会被发送一个<code>release</code>消息。如果被销毁的释放池不位于栈的顶部，那么位于它之上的所有释放池也会被销毁。</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[如何記憶C語言中運算符的優先級]]></title>
    <link href="http://lldong.github.com/blog/2011/04/10/how-to-memorize-c-operator-precedence/"/>
    <updated>2011-04-10T15:56:00+08:00</updated>
    <id>http://lldong.github.com/blog/2011/04/10/how-to-memorize-c-operator-precedence</id>
    <content type="html"><![CDATA[<p><code>之前在另外一個博客上的一篇學習筆記，整理出來放到這裏.</code></p>

<p>在使用C語言中，由於運算符優先級而引發的錯誤既常見又難以發覺。我們常武斷地使用了錯誤的優先級，導致常常是找到了出錯的表達式卻還是不得其解。通常避免出現這種錯誤的方法是使用 括號來確定其優先級，但是，對於比較長的表達式，加上括號後會導致其難以閱讀。所以，好好 地記憶一下運算符的優先級就有非常有必要了。下面就介紹一種不錯的記憶C語言運算符優先級的方法：</p>

<p>首先，我們把他們由高到低分成15個級別，然後再由高到底逐個級別進行分析，尋找其間的規律:</p>

<ol>
<li>先來看優先級最高的一組，這組運算符號的特點是它們中的大部分都不是正真意義上的運算符，它們分別是：(其中的自增<code>++</code>和自減<code>–</code>都是後綴運算符）:</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="p">()</span><span class="err">，</span> <span class="p">[]</span><span class="err">，</span> <span class="p">.</span><span class="err">，</span> <span class="o">-&gt;</span><span class="err">，</span> <span class="o">++</span><span class="err">，</span> <span class="o">--</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>第二組的成員是剩下來所有的一元運算符，它們分別是（其中的自增<code>++</code>和自減<code>--</code>都是後綴運算符）：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">++</span><span class="err">，</span> <span class="o">--</span><span class="err">，</span> <span class="o">+</span><span class="err">，</span> <span class="o">-</span><span class="err">，</span> <span class="o">~</span><span class="err">，</span> <span class="o">!</span><span class="err">，</span> <span class="o">*</span><span class="err">，</span> <span class="o">&amp;</span><span class="err">，</span> <span class="p">(</span><span class="n">type</span><span class="p">)</span><span class="err">，</span> <span class="k">sizeof</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>一元運算符之後就剩下二元運算符了，而二元運算符中優先級中最高的就是算術運算符這一 類，所以第三組是：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">*</span><span class="err">，</span> <span class="o">/</span><span class="err">，</span> <span class="o">%</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>可以由第3組推斷得出第四組是：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">+</span><span class="err">，</span> <span class="o">-</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>級別次於算術運算符的是位移運算符，所以這一組的成員是：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">&lt;&lt;</span><span class="err">，</span> <span class="o">&gt;&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>接下來這一類就是關係運算符了，第6組的成員有：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">&lt;</span><span class="err">，</span> <span class="o">&gt;</span><span class="err">，</span> <span class="o">&lt;=</span><span class="err">，</span> <span class="o">&gt;=</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>雖然都是關係運算符，但是 <code>==</code> 和 <code>!=</code> 的優先級要低一些，這樣我們就可以寫出諸如:<code>a&lt; b == c &gt; b</code>的判別式：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">==</span><span class="p">,</span> <span class="o">!=</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>次於關係運算符的是二元的位運算符，一共有三個，把它們分為三個組，這一組是：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">&amp;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>然後是：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">^</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>最後是：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">|</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>接著就是邏輯運算符這一類了，只有兩個，分成兩組，這組是：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">&amp;&amp;</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>然後：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">||</span>
</span></code></pre></td></tr></table></div></figure>


<p></p>

<ol>
<li>二元的運算符之後就好似三元運算符了，C語言中只有一個：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">?:</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>級別倒數第二高的是那些賦值運算符了，有很多：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="o">=</span><span class="err">，</span> <span class="o">+=</span><span class="err">，</span> <span class="o">-=</span><span class="err">，</span> <span class="o">*=</span><span class="err">，</span> <span class="o">/=</span><span class="err">，</span> <span class="o">^=</span><span class="err">，</span> <span class="o">%=</span><span class="err">，</span> <span class="o">&amp;=</span><span class="err">，</span><span class="o">|=</span><span class="err">，</span> <span class="o">&lt;&lt;=</span><span class="err">，</span> <span class="o">&gt;&gt;=</span>
</span></code></pre></td></tr></table></div></figure>


<ol>
<li>最後是優先級最低的逗號運算符：</li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="err">，</span>
</span></code></pre></td></tr></table></div></figure>


<p>分成這15個級別之後，讓我們再來總結一下。其中我們可以看出這樣兩個規律：</p>

<ul>
<li><p>按照操作數個數來區分，一元運算符高於二元運算符，二元運算符高於三元運算符；</p></li>
<li><p>按照運算符的作用來區分，級別最高的是那些不是嚴格意義上的運算符，次之是算術運 算符，位移運算符，關係運算符，位運算符，邏輯運算符，賦值運算符。</p></li>
</ul>


<p>此外還有兩特別的地方需要注意：</p>

<ul>
<li><p>同為關係運算符，但==和!=的級別低於其它四個；</p></li>
<li><p>第2、13和14組的操作符是右結合的，其它的都為左結合；通過分類我們大大減少了需要記憶的內容，遇到使用操作符的時候，我們只需想想它們是甚麼類型的運算符就可以確定它們之間的相對優先級，從而避免一些不必要的錯誤。</p></li>
</ul>

]]></content>
  </entry>
  
</feed>
