<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     >
  <channel>
    <title>mojavy.com</title>
    <link>http://mojavy.com/blog</link>
    <description></description>
    <pubDate>Thu, 18 Oct 2012 18:00:01 GMT</pubDate>
    <generator>Blogofile</generator>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>iOSでZeroMQを試す</title>
      <link>http://mojavy.com/blog/2012/10/18/objective-c-zeromq/</link>
      <pubDate>Thu, 18 Oct 2012 18:00:01 JST</pubDate>
      <category><![CDATA[objective-c]]></category>
      <category><![CDATA[ios]]></category>
      <category><![CDATA[zeromq]]></category>
      <category><![CDATA[common lisp]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2012/10/18/objective-c-zeromq/</guid>
      <description>iOSでZeroMQを試す</description>
      <content:encoded><![CDATA[<p><img alt="zeromq" src="/images/zeromq-logo.png" /></p>
<p><a href="http://mojavy.com/blog/2012/10/17/common-lisp-zeromq/">前回Common LispでZeroMQを試してみた</a>が、今度はiOSからも試してみた。<a href="http://www.zeromq.org/area:licensing">ZeroMQのライセンス</a>はLGPLだが、static linking exceptionがあるのでiPhoneアプリに組み込んでもソースは公開しなくて大丈夫なはず。(勘違いしてたらごめんなさい)</p>
<h1 id="zeromqiphone">ZeroMQをiPhone用にビルド</h1>
<p>ZeroMQはautotoolsで作成されておりconfigure &amp;&amp; make でビルドできるようになっているが、iPhone用にクロスコンパイルをするためには適切なオプションを与えてやる必要がある。</p>
<p>一応、<a href="http://www.zeromq.org/build:iphone">本家サイト上にもドキュメント</a>はあるが最新のXcodeではうごかない。また、シミュレータ用でもうごかせるようにしておきたい。というわけで、以下のようなビルドスクリプトを書いた。</p>
<script src="https://gist.github.com/3899653.js"> </script>

<p>これをZeroMQのtarを展開してできたディレクトリにbuild.shとかで保存して実行すると、armv7とi386に対応したlibzmq.aができる。</p>
<div class="pygments_borland"><pre><span class="nv">$ </span>tar xzf zeromq-2.2.0.tar.gz
<span class="nv">$ </span><span class="nb">cd </span>zeromq-2.2.0
<span class="nv">$ </span>./build.sh
<span class="nv">$ </span>file libzmq.a
libzmq.a: Mach-O universal binary with 2 architectures
libzmq.a <span class="o">(</span><span class="k">for </span>architecture armv7<span class="o">)</span>:      current ar archive random library
libzmq.a <span class="o">(</span><span class="k">for </span>architecture i386<span class="o">)</span>:       current ar archive random library
</pre></div>

<p>このlibzmq.aと、includeディレクトリの中身をXcodeにインポートしてやればよい。
このときに、XcodeでOther Linker Flags に -lstdc++ を追加してやるのを忘れないように。</p>
<h1 id="zeromq">ZeroMQを用いた簡易チャットアプリ</h1>
<p>サンプルとしてチャットアプリを実装してみる。
チャットでの発言はREQ/REPを用いてアプリ→サーバに渡し、PUB/SUBを用いてサーバ→アプリにブロードキャストする。</p>
<h2 id="_1">サーバ側</h2>
<p>サーバ側はCommon Lispで実装した。単に、rep-sockから発言を受け取ってpub-sockにそのまま流すだけ。</p>
<div class="pygments_borland"><pre>(load &quot;~/.sbclrc&quot;)
(ql:quickload :zeromq)

(defun pull-and-publish ()
  (zmq:with-context (ctx 1)
    (zmq:with-socket (rep-sock ctx zmq:rep)
      (zmq:bind rep-sock &quot;tcp://127.0.0.1:5555&quot;)

      (zmq:with-context (ctx2 1)
        (zmq:with-socket (pub-sock ctx2 zmq:pub)
          (zmq:bind pub-sock &quot;tcp://127.0.0.1:5556&quot;)

          (loop
             (let ((msg (make-instance &#39;zmq:msg)))
               (zmq:recv rep-sock msg)
               (zmq:send rep-sock (make-instance &#39;zmq:msg :data &quot;ok&quot;))
               (zmq:send pub-sock msg))))))))

(pull-and-publish)
</pre></div>

<p>REQ/REPではなくPULL/PUSHでもできるはずだが、なぜかcl-zmqではpullがつかえなかったのでREQ/REPをつかった。</p>
<h2 id="_2">アプリ側</h2>
<p><a href="https://github.com/jeremy-w/objc-zmq">objective-c版ZeroMQ</a>もあるけど、今回はそのままCのAPIを利用した。
以下はソースの抜粋。</p>
<div class="pygments_borland"><pre><span class="cp">#import &quot;ChatViewController.h&quot;</span>
<span class="cp">#import &quot;include/zmq.h&quot;</span>

<span class="k">@interface</span> <span class="nc">ChatViewController</span> <span class="p">()</span> <span class="p">{</span>

    <span class="kt">void</span> <span class="o">*</span><span class="n">ctx1</span><span class="p">,</span> <span class="o">*</span><span class="n">ctx2</span><span class="p">;</span>
    <span class="kt">void</span> <span class="o">*</span><span class="n">subsock</span><span class="p">,</span> <span class="o">*</span><span class="n">reqsock</span><span class="p">;</span>

    <span class="n">NSMutableArray</span> <span class="o">*</span><span class="n">messageList</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">@end</span>

<span class="err">@</span><span class="n">implementation</span> <span class="n">ChatViewController</span>

<span class="k">@synthesize</span> <span class="n">nickname</span><span class="p">;</span>
<span class="k">@synthesize</span> <span class="n">timer</span><span class="p">;</span>

<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">viewDidLoad</span>
<span class="p">{</span>
    <span class="p">[</span><span class="n">super</span> <span class="n">viewDidLoad</span><span class="p">];</span>

    <span class="n">ctx1</span> <span class="o">=</span> <span class="n">zmq_init</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="n">subsock</span> <span class="o">=</span> <span class="n">zmq_socket</span><span class="p">(</span><span class="n">ctx1</span><span class="p">,</span> <span class="n">ZMQ_SUB</span><span class="p">);</span>
    <span class="n">zmq_setsockopt</span><span class="p">(</span><span class="n">subsock</span><span class="p">,</span> <span class="n">ZMQ_SUBSCRIBE</span><span class="p">,</span> <span class="s">&quot;&quot;</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
    <span class="kt">int</span> <span class="n">rc</span> <span class="o">=</span> <span class="n">zmq_connect</span><span class="p">(</span><span class="n">subsock</span><span class="p">,</span> <span class="s">&quot;tcp://127.0.0.1:5556&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>

    <span class="n">ctx2</span> <span class="o">=</span> <span class="n">zmq_init</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="n">reqsock</span> <span class="o">=</span> <span class="n">zmq_socket</span><span class="p">(</span><span class="n">ctx1</span><span class="p">,</span> <span class="n">ZMQ_REQ</span><span class="p">);</span>
    <span class="n">rc</span> <span class="o">=</span> <span class="n">zmq_connect</span><span class="p">(</span><span class="n">reqsock</span><span class="p">,</span> <span class="s">&quot;tcp://127.0.0.1:5555&quot;</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>

    <span class="n">self</span><span class="p">.</span><span class="n">timer</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSTimer</span> <span class="nl">scheduledTimerWithTimeInterval:</span><span class="mi">1</span> <span class="nl">target:</span><span class="n">self</span> <span class="nl">selector:</span><span class="k">@selector</span><span class="p">(</span><span class="n">observeSocket</span><span class="p">)</span> <span class="nl">userInfo:</span><span class="nb">nil</span> <span class="nl">repeats:</span><span class="n">YES</span><span class="p">];</span>
    <span class="n">messageList</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSMutableArray</span> <span class="n">alloc</span><span class="p">]</span> <span class="n">init</span><span class="p">];</span>
<span class="p">}</span>

<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">viewWillDisappear:</span><span class="p">(</span><span class="kt">BOOL</span><span class="p">)</span><span class="nv">animated</span>
<span class="p">{</span>
    <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">timer</span> <span class="n">invalidate</span><span class="p">];</span>
    <span class="n">zmq_close</span><span class="p">(</span><span class="n">subsock</span><span class="p">);</span>
    <span class="n">zmq_close</span><span class="p">(</span><span class="n">reqsock</span><span class="p">);</span>
    <span class="n">zmq_term</span><span class="p">(</span><span class="n">ctx1</span><span class="p">);</span>
    <span class="n">zmq_term</span><span class="p">(</span><span class="n">ctx2</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">observeSocket</span>
<span class="p">{</span>
    <span class="n">zmq_msg_t</span> <span class="n">msg</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">rc</span> <span class="o">=</span> <span class="n">zmq_msg_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">msg</span><span class="p">);</span>
    <span class="n">assert</span><span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>

    <span class="k">do</span> <span class="p">{</span>
        <span class="n">rc</span> <span class="o">=</span> <span class="n">zmq_recv</span><span class="p">(</span><span class="n">subsock</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">msg</span><span class="p">,</span> <span class="n">ZMQ_NOBLOCK</span><span class="p">);</span>
        <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">EAGAIN</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;no data available&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">ENOTSUP</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;ENOTSUP&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">EFSM</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;EFSM&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">ETERM</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;ETERM&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">ENOTSOCK</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;ENOTSOCK&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">EINTR</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;EINTR&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="n">EFAULT</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;EFAULT&quot;</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
            <span class="n">size_t</span> <span class="n">siz</span> <span class="o">=</span> <span class="n">zmq_msg_size</span><span class="p">(</span><span class="o">&amp;</span><span class="n">msg</span><span class="p">);</span>
            <span class="kt">void</span> <span class="o">*</span><span class="n">dat</span> <span class="o">=</span> <span class="n">zmq_msg_data</span><span class="p">(</span><span class="o">&amp;</span><span class="n">msg</span><span class="p">);</span>
            <span class="n">NSString</span> <span class="o">*</span><span class="n">str</span> <span class="o">=</span> <span class="p">[[</span><span class="n">NSString</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithData:</span><span class="p">[</span><span class="n">NSData</span> <span class="nl">dataWithBytes:</span><span class="n">dat</span> <span class="nl">length:</span><span class="n">siz</span><span class="p">]</span> <span class="nl">encoding:</span><span class="n">NSUTF8StringEncoding</span><span class="p">];</span>
            <span class="p">[</span><span class="n">messageList</span> <span class="nl">insertObject:</span><span class="n">str</span> <span class="nl">atIndex:</span><span class="mi">0</span><span class="p">];</span>
        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
            <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;unknown&quot;</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span> <span class="k">while</span> <span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
    <span class="n">zmq_msg_close</span><span class="p">(</span><span class="o">&amp;</span><span class="n">msg</span><span class="p">);</span>
    <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">tableView</span> <span class="n">reloadData</span><span class="p">];</span>
<span class="p">}</span>

<span class="k">-</span> <span class="p">(</span><span class="kt">IBAction</span><span class="p">)</span> <span class="nf">saySomething:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">sender</span>
<span class="p">{</span>
    <span class="n">UIAlertView</span> <span class="o">*</span><span class="n">alert</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIAlertView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTitle:</span><span class="s">@&quot;text input&quot;</span>
                                <span class="nl">message:</span><span class="s">@&quot;&quot;</span>
                               <span class="nl">delegate:</span><span class="n">self</span>
                      <span class="nl">cancelButtonTitle:</span><span class="s">@&quot;cancel&quot;</span>
                      <span class="nl">otherButtonTitles:</span><span class="s">@&quot;ok&quot;</span><span class="p">,</span> <span class="nb">nil</span><span class="p">];</span>
    <span class="n">alert</span><span class="p">.</span><span class="n">alertViewStyle</span> <span class="o">=</span> <span class="n">UIAlertViewStylePlainTextInput</span><span class="p">;</span>
    <span class="p">[</span><span class="n">alert</span> <span class="n">show</span><span class="p">];</span>
<span class="p">}</span>

<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">alertView:</span><span class="p">(</span><span class="n">UIAlertView</span><span class="o">*</span><span class="p">)</span><span class="nv">alertView</span> <span class="nf">clickedButtonAtIndex:</span><span class="p">(</span><span class="n">NSInteger</span><span class="p">)</span><span class="nv">buttonIndex</span>
<span class="p">{</span>
    <span class="n">zmq_msg_t</span> <span class="n">msg</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">rc</span><span class="p">;</span>
    <span class="n">NSData</span> <span class="o">*</span><span class="n">data</span><span class="p">;</span>
    <span class="n">NSString</span> <span class="o">*</span><span class="n">str</span><span class="p">;</span>

    <span class="k">switch</span> <span class="p">(</span><span class="n">buttonIndex</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">case</span> <span class="mi">0</span><span class="o">:</span>
            <span class="k">break</span><span class="p">;</span>
        <span class="k">case</span> <span class="mi">1</span><span class="o">:</span>
            <span class="n">str</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSString</span> <span class="nl">stringWithFormat:</span><span class="s">@&quot;%@: %@&quot;</span><span class="p">,</span> <span class="n">nickname</span><span class="p">,</span> <span class="p">[</span><span class="n">alertView</span> <span class="nl">textFieldAtIndex:</span><span class="mi">0</span><span class="p">].</span><span class="n">text</span><span class="p">];</span>
            <span class="n">data</span> <span class="o">=</span> <span class="p">[</span><span class="n">str</span> <span class="nl">dataUsingEncoding:</span><span class="n">NSUTF8StringEncoding</span><span class="p">];</span>
            <span class="n">rc</span> <span class="o">=</span> <span class="n">zmq_msg_init_size</span><span class="p">(</span><span class="o">&amp;</span><span class="n">msg</span><span class="p">,</span> <span class="p">[</span><span class="n">data</span> <span class="n">length</span><span class="p">]);</span>
            <span class="n">assert</span><span class="p">(</span><span class="n">rc</span> <span class="o">==</span> <span class="mi">0</span><span class="p">);</span>
            <span class="n">memcpy</span><span class="p">(</span><span class="n">zmq_msg_data</span><span class="p">(</span><span class="o">&amp;</span><span class="n">msg</span><span class="p">),</span> <span class="p">[</span><span class="n">data</span> <span class="n">bytes</span><span class="p">],</span> <span class="p">[</span><span class="n">data</span> <span class="n">length</span><span class="p">]);</span>

            <span class="n">zmq_send</span><span class="p">(</span><span class="n">reqsock</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">msg</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
            <span class="n">zmq_recv</span><span class="p">(</span><span class="n">reqsock</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">msg</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
            <span class="n">zmq_msg_close</span><span class="p">(</span><span class="o">&amp;</span><span class="n">msg</span><span class="p">);</span>
            <span class="k">break</span><span class="p">;</span>
        <span class="k">default</span><span class="o">:</span>
            <span class="k">break</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">@end</span>
</pre></div>

<p>以下補足</p>
<ul>
<li>簡単のためタイマーで1秒ごとにソケットにメッセージがあるかどうかobserveSocketでチェックしているが、別スレッドにしたほうがスマート</li>
<li><a href="http://api.zeromq.org/2-2:zmq-recv">zmq_recvのマニュアル</a>によると、zmq_recvをZMQ_NOBLOCKで呼んだときにメッセージがなかった場合はEAGAINが返るとなっているが、-1がかえってきていた。</li>
<li>上記ソースはUITableViewControllerで発言を表示する想定になっているが、UIまわりのコードは省略</li>
</ul>
<h2 id="common-lisp">オマケ(Common Lisp版コマンドライン用チャットクライアント)</h2>
<div class="pygments_borland"><pre>(load &quot;~/.sbclrc&quot;)
(ql:quickload :zeromq)
(ql:quickload :bordeaux-threads)

(defun sub ()
  (zmq:with-context (ctx 1)
    (zmq:with-socket (socket ctx zmq:sub)
      (zmq:setsockopt socket zmq:subscribe &quot;&quot;)
      (zmq:connect socket &quot;tcp://127.0.0.1:5556&quot;)
      (loop
         (let ((query (make-instance &#39;zmq:msg)))
           (zmq:recv socket query)
           (format t &quot;received message: ~a~%&quot; (zmq:msg-data-as-string query)))))))

(defun client ()
  (zmq:with-context (ctx 1)
    (zmq:with-socket (socket ctx zmq:req)
      (zmq:connect socket &quot;tcp://127.0.0.1:5555&quot;)
      (loop
         (zmq:send socket (make-instance &#39;zmq:msg
                                         :data (read-line)))
         (let ((result (make-instance &#39;zmq:msg)))
           (zmq:recv socket result))))))

(bordeaux-threads:make-thread #&#39;sub)
(client)
</pre></div>

<h1 id="_3">まとめ</h1>
<ul>
<li>iPhoneでZeroMQを動かしてみた</li>
<li>ZeroMQのREQ/REPとPUB/SUBを使用してチャットをつくってみた</li>
<li>appleの審査を通過するかどうかは知らない(一応実績はあるらしい)</li>
</ul>
<h1 id="_4">参考</h1>
<ul>
<li><a href="http://api.zeromq.org/2-2:_start">http://api.zeromq.org/2-2:_start</a></li>
<li><a href="http://www.zeromq.org/area:licensing">http://www.zeromq.org/area:licensing</a></li>
<li><a href="http://www.zeromq.org/intro:commercial-support">http://www.zeromq.org/intro:commercial-support</a></li>
</ul>]]></content:encoded>
    </item>
    <item>
      <title>objective-cのメモリマネージメントについて</title>
      <link>http://mojavy.com/blog/2012/07/18/objective-c-memo-memory-management/</link>
      <pubDate>Wed, 18 Jul 2012 11:30:00 JST</pubDate>
      <category><![CDATA[objective-c]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2012/07/18/objective-c-memo-memory-management/</guid>
      <description>objective-cのメモリマネージメントについて</description>
      <content:encoded><![CDATA[<p><img alt="objective-c" src="/images/nextstep-logo.png" /></p>
<p>現在のところ3つの方法がある</p>
<h2 id="1-gabage-collection">1. Gabage Collection</h2>
<ul>
<li>Objective-C 2.0から導入された。</li>
<li>ただし、iOSの実行環境には含まれない。</li>
<li>Max OS Xでなら使えるらしい。</li>
</ul>
<h2 id="2-manual-reference-counting">2. Manual Reference Counting</h2>
<ul>
<li>retainは参照カウントを1あげる。releaseは1さげる</li>
<li>参照カウントが0でdeallocするとすぐに削除される</li>
<li>NSMutableArrayのaddObjectやremoveObjectAtIndexなどはオブジェクトの参照カウントを増減させる。</li>
<li>余分にreleaseしたりするとcrashする</li>
</ul>
<h2 id="3-automatic-reference-counting-arc">3. Automatic Reference Counting (ARC)</h2>
<ul>
<li>システムが自動的に参照カウントをしてくれる。</li>
<li>強い変数と弱い変数がある</li>
</ul>
<h4 id="_1">強い変数</h4>
<ul>
<li>デフォルトでは、オブジェクトのポインタは強い変数。そのようなポインタにアサインした参照は自動的にretainされる。</li>
<li>新しい参照をアサインする前に古い参照はreleaseされる</li>
<li>_ _strong キーワードをつかって明示的に強い変数を宣言できる。</li>
<li>プロパティはデフォルトではstrongではない</li>
<li>C++のshared_ptrのようなもの？</li>
</ul>
<h4 id="_2">弱い変数</h4>
<ul>
<li>循環参照している場合や、しても開放されるようにするときに使える。</li>
<li>親が子の強い参照を持っており、子が親の弱い参照を持っている場合、retainのサイクルが形成されなくなるのでオブジェクトを開放できる。</li>
<li>_ _weakキーワードを使う。</li>
<li>iOS4ではサポートされていない</li>
<li>C++のweak_ptrのようなもの？</li>
</ul>
<h4 id="non-arc">Non-ARCのコード</h4>
<ul>
<li>init, alloc, copy, new, mutableCopyをprefixにもつメソッドはそのオブジェクトの所有権を返す、というネーミングコンベンションに従っている場合は自動的にARCが適用される。</li>
<li>名前のコンベンションとは関係なしに、明示的にオブジェクトの所有権を返すメソッドをコンパイラに伝える方法もある。</li>
</ul>
<h2 id="_3">参考</h2>
<p><br>
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=armyofpigs-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=0321811909" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>]]></content:encoded>
    </item>
    <item>
      <title>objective-cのプロトコルとデリゲーションについてのメモ</title>
      <link>http://mojavy.com/blog/2012/07/17/objective-c-memo-protocol/</link>
      <pubDate>Tue, 17 Jul 2012 18:30:00 JST</pubDate>
      <category><![CDATA[objective-c]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2012/07/17/objective-c-memo-protocol/</guid>
      <description>objective-cのプロトコルとデリゲーションについてのメモ</description>
      <content:encoded><![CDATA[<p><img alt="objective-c" src="/images/nextstep-logo.png" /></p>
<ul>
<li>プロトコルとはクラス間で共有するメソッドのリスト。</li>
<li>javaでいうinterfaceのようなもの。</li>
<li>@optionalディレクティブ以降のメソッドは実装が任意。</li>
<li>@requiredディレクティブで必須。</li>
<li>プロトコルに必要なメソッドは直接そのクラスで実装してもいいし、継承元の親クラスで実装してもよい。</li>
<li>requiredがすべて実装されていなかった場合、コンパイラーはワーニングを出す。(エラーではない)</li>
<li>すべてのrequiredメソッドを実装したクラスはそのプロトコルにconform(もしくはadopt)したという。</li>
<li>そのオブジェクトがconformしているかどうかチェックするには、conformsToProtocolメソッドを使う。</li>
<li>そのオブジェクトがoptionalなメソッドを実装しているかどうかをチェックするには、respondsToSelectorを使う。</li>
<li>コンパイル時に型チェックが行われる。型宣言に<protocol名>を含めるとよい。</li>
<li>カテゴリもプロトコルにadoptできる。</li>
<li>プロトコルの名前はユニークでなければならない。</li>
<li>delegationとはプロトコルで定義されたメソッドを実装したクラスを定義すること。</li>
<li>informal protocolというものもあるが、これは単に実装がないカテゴリのこと。abstract protocolともいう。ドキュメンテーションやモジュラリティのために用いる。コンパイル時チェックはなし。プロトコルの@optionalディレクトリはObjective-C 2.0で追加されたので、こちらをつかえばよい。</li>
<li>eclipseでいうデリゲートは、Composite Objectとよばれる</li>
</ul>
<h2 id="_1">例</h2>
<h3 id="myprotocolh">myProtocol.h</h3>
<div class="pygments_borland"><pre><span class="cp">#import &lt;Foundation/Foundation.h&gt;</span>

<span class="k">@protocol</span> <span class="nc">myProtocol</span> <span class="o">&lt;</span><span class="n">NSObject</span><span class="o">&gt;</span>

<span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">f1</span><span class="p">;</span>
<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">f2:</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">obj0</span> <span class="nf">withObject1:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">obj1</span><span class="p">;</span>

<span class="k">@end</span>
</pre></div>

<h3 id="myprotocolimplh">myProtocolImpl.h</h3>
<div class="pygments_borland"><pre><span class="cp">#import &lt;UIKit/UIKit.h&gt;</span>
<span class="cp">#import &quot;myProtocol.h&quot;</span>

<span class="k">@interface</span> <span class="nc">myProtocolImpl</span> : <span class="nc">NSObject</span> <span class="o">&lt;</span><span class="n">myProtocol</span><span class="o">&gt;</span>

<span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">f1</span><span class="p">;</span>
<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">f2:</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">obj0</span> <span class="nf">withObject1:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">obj1</span><span class="p">;</span>

<span class="k">@end</span>
</pre></div>

<h3 id="myprotocolimplm">myProtocolImpl.m</h3>
<div class="pygments_borland"><pre><span class="cp">#import &quot;myProtocolImpl.h&quot;</span>

<span class="k">@implementation</span> <span class="nc">myProtocolImpl</span>

<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">f1</span>
<span class="p">{</span>
    <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;called f0&quot;</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nf">f2:</span> <span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">obj0</span> <span class="nf">withObject1:</span><span class="p">(</span><span class="kt">id</span><span class="p">)</span><span class="nv">obj1</span>
<span class="p">{</span>
    <span class="n">NSLog</span><span class="p">(</span><span class="s">@&quot;called f2&quot;</span><span class="p">);</span>
<span class="p">}</span>

<span class="k">@end</span>
</pre></div>

<h2 id="_2">参考</h2>
<p><br>
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=armyofpigs-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=0321811909" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>]]></content:encoded>
    </item>
    <item>
      <title>objective-cのカテゴリついてのメモ</title>
      <link>http://mojavy.com/blog/2012/07/13/objective-c-memo/</link>
      <pubDate>Fri, 13 Jul 2012 18:30:00 JST</pubDate>
      <category><![CDATA[objective-c]]></category>
      <guid isPermaLink="true">http://mojavy.com/blog/2012/07/13/objective-c-memo/</guid>
      <description>objective-cのカテゴリついてのメモ</description>
      <content:encoded><![CDATA[<p><img alt="objective-c" src="/images/nextstep-logo.png" /></p>
<ul>
<li>objective-cではカテゴリという機能を使ってクラスの拡張ができる。</li>
<li>javascriptのprototypeのようなもの。</li>
<li>一旦上書きしたメソッドにアクセスする方法はない。メソッドを上書きする必要がある場合はサブクラスとして実装するべき。</li>
<li>プライベートメソッドは無名カテゴリを使って実装できる。</li>
<li>別の名前のカテゴリでもメソッド名は一意にしなければならない。</li>
<li>別のカテゴリとの間にメソッド名でコンフリクトが発生した場合、どちらが呼ばれるかは未定義。</li>
<li>カテゴリ名自体にソースコード上での可読性以上の実質的な意味は無いらしい。</li>
</ul>
<h2 id="_1">例</h2>
<div class="pygments_borland"><pre><span class="k">@interface</span> <span class="nc">NSObject</span> <span class="nl">(MyExt)</span>
<span class="k">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">doit:</span> <span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span> <span class="n">arg</span><span class="p">;</span>
<span class="k">@end</span>

<span class="k">@implementation</span> <span class="nc">NSObject</span> <span class="nl">(MyExt)</span>
<span class="k">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span> <span class="nf">doit:</span> <span class="p">(</span><span class="n">NSString</span> <span class="o">*</span><span class="p">)</span> <span class="n">arg</span>
<span class="p">{</span>
   <span class="c1">// do something</span>
<span class="p">}</span>
<span class="k">@end</span>
</pre></div>

<h2 id="_2">参考</h2>
<ul>
<li><a href="http://stackoverflow.com/questions/5689088/do-objective-c-category-names-do-anything">http://stackoverflow.com/questions/5689088/do-objective-c-category-names-do-anything</a></li>
</ul>
<p><br>
<iframe src="http://rcm-jp.amazon.co.jp/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=armyofpigs-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=0321811909" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>]]></content:encoded>
    </item>
  </channel>
</rss>
