<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>My Codex Leicester</title>
	<atom:link href="http://nagano.monalisa-au.org/feed" rel="self" type="application/rss+xml" />
	<link>http://nagano.monalisa-au.org</link>
	<description>Mac/iOS の Audio Visual Programmingの話題</description>
	<lastBuildDate>Mon, 13 May 2013 14:03:50 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>[Hello, Core Foundation] 07 CFTypeとそのメソッド(6) CFEqual, CFTypeID</title>
		<link>http://nagano.monalisa-au.org/archives/1795</link>
		<comments>http://nagano.monalisa-au.org/archives/1795#comments</comments>
		<pubDate>Sat, 27 Apr 2013 13:24:27 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Foundation]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1795</guid>
		<description><![CDATA[前回までで、基本クラスを一通り扱ったので、CFTypeの残りのメソッドを見ていきます。 ようやくCFTypeの全容が見えてきます。 残りは Memory Management CFGetAllocator CFGetRe [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://nagano.monalisa-au.org/archives/1746">前回</a>までで、基本クラスを一通り扱ったので、CFTypeの残りのメソッドを見ていきます。
ようやくCFTypeの全容が見えてきます。</p>

<p>残りは</p>

<p><strong>Memory Management</strong></p>

<ul>
<li><strong>CFGetAllocator</strong></li>
<li>CFGetRetainCount</li>
<li>CFRelease</li>
<li>CFRetain</li>
</ul>

<p><strong>Determining Equality</strong></p>

<ul>
<li><strong>CFEqual</strong></li>
</ul>

<p><strong>Hashing</strong></p>

<ul>
<li><strong>CFHash</strong></li>
</ul>

<p><strong>Miscellaneous Functions</strong></p>

<ul>
<li><strong>CFCopyDescription</strong></li>
<li><strong>CFCopyTypeIDDescription</strong></li>
<li><strong>CFGetTypeID</strong></li>
<li>CFShow</li>
</ul>

<p>です。今回はCFEqualとCFType関係を扱います。</p>

<h2>CFEqual</h2>

<p>引数の二つのオブジェクトが同一かどうかを返します。
CFBooleanを扱ったときにすでに一度使いました。
Core Foundationには、FoundationにおけるisEqualTo***に該当するメソッドは一切なく、すべてのクラスはこのメソッドを使います。</p>

<p>同一性が何で決まるのかは
<a href="https://developer.apple.com/library/mac/documentation/CoreFOundation/Reference/CFTypeRef/Reference/reference.html#//apple_ref/c/func/CFEqual">ドキュメント</a>を見ると</p>

<blockquote>
  <p>Equality is something specific to each Core Foundation opaque type.<br />
  同一性は、各Core Foundationオブジェクトごとに決まっている</p>
</blockquote>

<p>とあります。そしてCFNumberとCFStringについて例が書いてあります。</p>

<blockquote>
  <p>two CFNumber objects are equal if the numeric values they represent are equal.<br />
  CFNumberの場合、数値が同じならイコールになる。</p>
  
  <p>Two CFString objects are equal if they represent identical sequences of characters, regardless of encoding.<br />
  CFStringの場合、エンコーディングは関係なく、文字列として同じならイコールになる。</p>
</blockquote>

<p>つまり、簡単にまとめると、同一性の判断は持っている値なりの表現を対象に行われる、ということになります。
コレクションクラスの場合は、コレクションが同じかどうかが条件となります。</p>

<p>以上のルールから、基本クラスの同一性を判断するための比較対象は次のようになります。</p>

<table>
<thead>
<tr>
  <th align="left">クラス　　　　　　</th>
  <th>比較対象</th>
</tr>
</thead>
<tbody>
<tr>
  <td align="left">CFString</td>
  <td>(エンコーディングは関係なく)文字列</td>
</tr>
<tr>
  <td align="left">CFNumber</td>
  <td>数値</td>
</tr>
<tr>
  <td align="left">CFData</td>
  <td>バッファ</td>
</tr>
<tr>
  <td align="left">CFArray</td>
  <td>すべての要素とその順序</td>
</tr>
<tr>
  <td align="left">CFDictionary</td>
  <td>すべてのエントリー(KeyとValueの組み合わせ)</td>
</tr>
<tr>
  <td align="left">CFDate</td>
  <td>Absolute Time</td>
</tr>
</tbody>
</table>

<p>もう一つ、比較対象のみを見るため<strong>Mutable型とImmutable型は区別されません</strong>。
そのため、CFArrayもCFMutableArrayも比較対象が同じであればイコールになります。</p>

<p>基本クラスの例を見てみましょう。</p>

<pre class="brush: objc; title: ; notranslate">
//CFString
{
    CFStringRef string1 = CFSTR("yes");
    CFStringRef string2 = CFSTR("yes");
    printf("string1 : string2 = %d\n", CFEqual(string1, string2));
}

//CFArray
{
    const void *values1[] = {CFSTR("a"), CFSTR("b"), CFSTR("c")};
    CFArrayRef array1 = CFArrayCreate(kCFAllocatorDefault, values1, 3, NULL);
    const void *values2[] = {CFSTR("a"), CFSTR("b"), CFSTR("c")};
    CFArrayRef array2 = CFArrayCreate(kCFAllocatorDefault, values2, 3, NULL);

    CFMutableArrayRef array3 = CFArrayCreateMutable(kCFAllocatorDefault,
                                                    3,
                                                    &#038;kCFTypeArrayCallBacks);

    CFArrayAppendValue(array3, CFSTR("a"));
    CFArrayAppendValue(array3, CFSTR("b"));
    CFArrayAppendValue(array3, CFSTR("c"));

    printf("array1 : array2 = %d\n", CFEqual(array1, array2));
    printf("array1 : array3 = %d\n", CFEqual(array1, array3));

    CFRelease(array1);
    CFRelease(array2);
    CFRelease(array3);
}

//CFData
{
    const UInt8 bytes1[] = {0,1,2,3,4};
    CFDataRef data1 = CFDataCreate(kCFAllocatorDefault, bytes1, 5);
    const UInt8 bytes2[] = {0,1,2,3,4};
    CFDataRef data2 = CFDataCreate(kCFAllocatorDefault, bytes2, 5);

    printf("data1 : data2 = %d\n", CFEqual(data1, data2));

    CFRelease(data1);
    CFRelease(data2);
}

//CFNumber
{
    CFIndex one = 1;
    char onec = 1;
    float onef = 1.0;
    CFNumberRef number1, number2, numberf;
    number1 = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &#038;one);
    number2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberCharType, &#038;onec);
    numberf = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &#038;onef);

    printf("number1 : number2 = %d\n", CFEqual(number1, number2));
    printf("number1 : numberf = %d\n", CFEqual(number1, numberf));
    CFRelease(number1);
    CFRelease(number2);
    CFRelease(numberf);
}

//CFDictionary
{
    const CFTypeRef keys[] = {CFSTR("key0"), CFSTR("key1")};
    const CFTypeRef values[] = {CFSTR("value0"), CFSTR("value1")};

    CFDictionaryRef dictionary1;
    dictionary1 = CFDictionaryCreate(kCFAllocatorDefault,
                                    (const void**)keys,
                                    (const void**)values,
                                    2,
                                    &#038;kCFTypeDictionaryKeyCallBacks,
                                    NULL);
    
    CFTypeRef getKeys[2];
    CFDictionaryGetKeysAndValues(dictionary1, getKeys, NULL);
    
    const CFTypeRef keys2[] = {CFSTR("key1"), CFSTR("key0")};
    const CFTypeRef values2[] = {CFSTR("value1"), CFSTR("value0")};

    CFDictionaryRef dictionary2;
    dictionary2 = CFDictionaryCreate(kCFAllocatorDefault,
                                     (const void**)keys2,
                                     (const void**)values2,
                                     2,
                                     &#038;kCFTypeDictionaryKeyCallBacks,
                                     NULL);
    printf("dictionary1 : dictionary2 = %d\n", CFEqual(dictionary1, dictionary2));
    CFRelease(dictionary1);
    CFRelease(dictionary2);
}
    
//CFDate
{
    CFAbsoluteTime time1 = 12345;
    CFAbsoluteTime time2 = 12345;
    CFDateRef date1, date2;
    date1 = CFDateCreate(kCFAllocatorDefault, time1);
    date2 = CFDateCreate(kCFAllocatorDefault, time2);
    printf("date1 : date2 = %d\n", CFEqual(date1, date2));
    CFRelease(date1);
    CFRelease(date1);
}
</pre>

<p>実行結果はすべてtrueになります。</p>

<p>注目したいのは、CFNumberの例で、floatとintegerの比較がtrueになっています。
<pre class="brush: objc; title: ; notranslate">
printf(&quot;number1 : numberf = %d\n&quot;, CFEqual(number1, numberf));
</pre>
これは
1 == 1.0 が 真だからです。
CFArrayの例では、Mutable型とImmutable型を比較しています。これもtrueになります。
CFDictionaryの例ではKeyとValueを渡す順番を逆にしているのですが、trueになっています。これで順番が関係ないことが分かります。CFDateもCFNumberと考え方は同じで、CFAbsoluteTime同士が == が真ならtrueとなります。</p>

<h2>CFGetTypeID</h2>

<p>CFGetTypeIDメソッドはあるオブジェクトがどのクラスのオブジェクトなのかを判定するための一意な値(ID)を返すメソッドです。</p>

<pre class="brush: objc; title: ; notranslate">
CFTypeID CFGetTypeID (CFTypeRef cf);
</pre>

<p>戻り値はCFTypeID型で、クラスごとにユニークな値を返します。
Core Foundationのオブジェクトは便宜上クラスと読んではいますが、正確には不透過型なのでgetClassNameのようなメソッドがありません。そのかわりにCFGetTypeIDが存在している、と考えると理解しやすいと思います。C言語には型を動的に判定する仕組が存在しないので、このような仕組みが導入されています。</p>

<p>CFEqualでは、あるオブジェクトとオブジェクトが同じクラスであるかどうかは判定できません。
この判定を行いたい場合にも、CFGetTypeIDメソッドを使います。</p>

<p>注意点としては、CFGetTypeIDが返すCFTypeIDの値は実装によって変わる可能性があるため、どのCore Foundationのバージョンでも常に同じ値を返すとは限りません。
そのため、CFGetTypeIDが返す実際の値に依存したコードを書いてはいけません。</p>

<h2>{ClassName}GetTypeID</h2>

<p>たとえば、あるオブジェクトがCFArrayのオブジェクトかどうか判定するにはどうすればいいのか。
Core Foundationのクラスは必ずClassName + GetTypeIDというメソッドを必ず持っているのでこれを使います
たとえばCFStringはCFStringGetTypeIDを持っています。</p>

<p>以下のようにして使います。</p>

<pre class="brush: objc; title: ; notranslate">
CFTypeRef obj; //どのクラスのオブジェクトか分からない

CFTypeID typeID = CFGetTypeID(obj);
if (CFStringGetTypeID() == typeID){
    printf("obj == CFString object!")
}else if (CFNumberGetTypeID() == typeID){
    printf("obj == CFNumber object!")
}
</pre>

<p>Core Foundationの中で最も小さいクラス、CFNullはCFNullGetTypeIDメソッドのみを持っています。</p>

<pre class="brush: objc; title: ; notranslate">
typedef const struct __CFNull * CFNullRef;

CF_EXPORT
CFTypeID CFNullGetTypeID(void);

CF_EXPORT
const CFNullRef kCFNull;    // the singleton null instance
</pre>

<h2>CFCopyTypeIDDescription</h2>

<p>CFCopyTypeIDDescriptionは、CFTypeIDを渡すと、CFTypeIDのdescriptionを返してくれるメソッドです。メソッド名にCopyと付いているのでオーナーシップを持つことに注意しましょう。</p>

<pre class="brush: objc; title: ; notranslate">
CFStringRef CFCopyTypeIDDescription (
   CFTypeID type_id
);
</pre>

<p>基本クラスで実行してみると、現状ではそれぞれクラス名を返します。
しかし、ドキュメントにもデバッグ用と明記されているように、このメソッドが返す値に依存したコードを書いてはいけません。</p>

<pre class="brush: objc; title: ; notranslate">
CFTypeID typeIDs[6] = {
    CFStringGetTypeID(),
    CFNumberGetTypeID(),
    CFDataGetTypeID(),
    CFArrayGetTypeID(),
    CFDictionaryGetTypeID(),
    CFDateGetTypeID()
};

for (CFIndex i = 0; i < 6; i++) {
    CFStringRef typeIDDesc = CFCopyTypeIDDescription(typeIDs[i]);
    CFShow(typeIDDesc);
    CFRelease(typeIDDesc);
}
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
CFString
CFNumber
CFData
CFArray
CFDictionary
CFDate
</pre>

<h2>CFType型のオブジェクトを取得する</h2>

<p>余談になりますが、最近ふとCFType型のオブジェクトを作成する方法を思いつきました。</p>

<blockquote class="twitter-tweet"><p>ふと思いついてNSObjectのインスタンスをToll-free bridgingしてCFGetTypeIDしたら、CFTypeGetTypeID(っていうCFTypeのTypeIDを返すPrivate関数)と同じ値だった。つまりはそういうことだ</p>&mdash; Norihisa Nagano (@7gano) <a href="https://twitter.com/7gano/status/333225945106374656">May 11, 2013</a></blockquote>

<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

<pre class="brush: objc; title: ; notranslate">
NSObject *object = [[NSObject alloc] init];
CFTypeRef cfType = (__bridge CFTypeRef)object;
</pre>

<p>そしてこのコードが正解かどうかは、CFCopyTypeIDDescriptionで型名を取得すれば分かります。</p>

<p>CFTypeGetTypeID()はプライベート関数です。</p>

<pre class="brush: objc; title: ; notranslate">
printf("%d\n", CFTypeGetTypeID() == CFGetTypeID(cfType));
CFStringRef typeIDDesc = CFCopyTypeIDDescription(CFTypeGetTypeID());
CFShow(typeIDDesc);
CFRelease(typeIDDesc);
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
1
CFType
</pre>

<p>ドキュメントにも記述がありませんし、できたところで用途がありませんが、面白いですね。</p>

<h2>ポリモーフィズム</h2>

<p>クラスによって挙動が変わるが、インターフェイスは同じ、というのはオブジェクト指向ではポリモーフィズムと呼ばれます。</p>

<p><a href="http://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%95%E3%82%A3%E3%82%BA%E3%83%A0">ポリモーフィズム(多態性)</a></p>

<blockquote>
  <p>プログラミング言語の型システムの性質を表すもので、プログラミング言語の各要素（定数、変数、式、オブジェクト、関数、メソッドなど）についてそれらが<strong>複数の型に属することを許す</strong>という性質を指す。</p>
</blockquote>

<p>もし、CFShowがなく、クラスごとにCFNumberShow, CFStringShow , CFArrayShowのようなメソッドがあるとすると</p>

<pre class="brush: objc; title: ; notranslate">
CFShow(obj);
</pre>

<p>で済む処理が</p>

<pre class="brush: objc; title: ; notranslate">
    CFTypeID typeID = CFGetTypeID(obj)
    switch (typeID) {
        case CFNumberGetTypeID()
            CFNumberShow(obj);
            break;

        case CFStringGetTypeID()
            CFStringShow(obj);
            break;

        case CFArrayGetTypeID()
            CFArrayShow(obj);
            break;

        default:
            break;
    }
</pre>

<p>のように分岐だらけになってしまいます。実際、CFShowの実装はCFGetTypeIDが返す値をインデックスとした関数のポインタの配列があり、オブジェクトごとに違う関数を呼び出すようになっています。</p>

<p>CFTypeが持つメソッドのように、ポリモーフィズムに対応した関数を<strong>ポリモーフィック関数</strong>と呼びます。</p>

<p>次回はCFHashを扱います。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1795/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Hello, Core Foundation] 06 CFTypeとそのメソッド(5) 基本的なクラス群 CFData, CFDictionary, CFDate</title>
		<link>http://nagano.monalisa-au.org/archives/1746</link>
		<comments>http://nagano.monalisa-au.org/archives/1746#comments</comments>
		<pubDate>Fri, 26 Apr 2013 12:06:39 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Foundation]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1746</guid>
		<description><![CDATA[前回はCFArrayとCFNumberを紹介して、コレクションクラスとCompareについて書きました。 今回はCFData、CFDictionary、CFDateを見てみましょう。 CFData CFDataはドキュメ [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://nagano.monalisa-au.org/archives/1701">前回</a>はCFArrayとCFNumberを紹介して、コレクションクラスとCompareについて書きました。
今回はCFData、CFDictionary、CFDateを見てみましょう。</p>

<h2>CFData</h2>

<p>CFDataはドキュメントによると、byte buffersを扱う(ラッパー)クラスである、Core Foundationのオブジェクトとして振る舞うことができるバッファである、と書かれています。
NSDataとToll-free bridging可能です。Mutable型のCFMutableDataがあります。</p>

<p>特に難しい点はありませんが、いくつか例を見ておきましょう。</p>

<pre class="brush: objc; title: ; notranslate">
{
    const UInt8 bytes[] = {0,1,2,3,4};
    CFDataRef data = CFDataCreate(kCFAllocatorDefault, bytes, 5);
    CFShow(data);
    CFRelease(data);
}

{
    UInt8 *bytes = malloc(sizeof(UInt8) * 10);
    memset(bytes, 1, sizeof(UInt8) * 10);
    CFDataRef data = CFDataCreate(kCFAllocatorDefault, bytes, 10);
   
    //CFDataCreate時にcopyされるので、ここでfreeしても大丈夫
    free(bytes);
 
    CFShow(data);
    CFRelease(data);
}

{
    UInt8 *bytes = malloc(sizeof(UInt8) * 10);
    memset(bytes, 1, sizeof(UInt8) * 10);
    CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
                                                           bytes,
                                                           10,
                                                           kCFAllocatorDefault);
                                                          
    //CFDataCreate時にcopyされないのでfreeすると
　　 //その後、開放済み領域にアクセスすることになりクラッシュする
    free(bytes);
    CFShow(data);
    CFRelease(data);
}
</pre>

<p>CFDataは通常、渡されたバッファを内部バッファにコピーします。
つまり、渡したバッファをfree()するまでの間は、二倍のメモリを使うことになります。
巨大なデータを扱うなど、これがメモリ管理上問題となる場合には</p>

<p><pre class="brush: objc; title: ; notranslate">
CFDataCreateWithBytesNoCopy
</pre></p>

<p>を使うと、バッファがコピーされません。この場合、バッファの管理をオブジェクトのメモリ管理と一緒に行う必要があります。
3番目の例はCFDataCreateWithBytesNoCopyを使い、かつオブジェクトが参照しているバッファを先にfree()しているため、実行するとクラッシュします。</p>

<pre class="brush: objc; title: ; notranslate">
CFRelease(data);
free(bytes);
</pre>

<p>としなければなりません。NoCopyという名前のメソッドは他にも多数存在しますので、覚えておきましょう。</p>

<p>修正した場合の実行結果</p>

<pre class="brush: objc; title: ; notranslate">
 &lt;CFData 0x100107ff0 [0x7fff7b6bf110]>{length = 5, capacity = 5, bytes = 0x0001020304}
 &lt;CFData 0x100107ff0 [0x7fff7b6bf110]>{length = 10, capacity = 10, bytes = 0x01010101010101010101}
 &lt;CFData 0x10010a410 [0x7fff7b6bf110]>{length = 10, capacity = 10, bytes = 0x01010101010101010101}
</pre>

<p>CFDataのメソッドを眺めていて気付くのは、
NSData#writeToFile
に準ずるメソッドがないことです。Core Foundationオブジェクトの永続化は後ほどやります。</p>

<h2>CFDictionary</h2>

<p>次に、CFDictionaryを見てみましょう。
CFDictionaryはkeyとvalueのペアの関連を管理するクラス、と説明されています。ペアのことをエントリーと呼びます。エントリーには順番という概念はありません。
Keyはユニークとして扱われるため、重複できません。
また、KeyとValueはCFArrayと同じくCFType以外のCの型も扱えますが、CFPropertyListでXMLを扱うときにはCFStringでなければなりません。
NSDictionaryとToll-free bridging可能です。
Mutable型のCFMutableDictionaryがあります。</p>

<p>連想配列、辞書、ハッシュと、いろいろな呼び方がありますが
Pythonのdictionary型、JavaのHashMapクラス、RubyのHashクラスと同様のものです。</p>

<pre class="brush: objc; title: ; notranslate">
const CFTypeRef keys[] = {CFSTR("key0"), CFSTR("key1")};
const CFTypeRef values[] = {CFSTR("value0"), CFSTR("value1")};

CFDictionaryRef dictionary;
dictionary = CFDictionaryCreate(kCFAllocatorDefault,
                                (const void**)keys,
                                (const void**)values,
                                2,
                                &#038;kCFTypeDictionaryKeyCallBacks,
                                &#038;kCFTypeDictionaryValueCallBacks);
CFShow(dictionary);
CFRelease(dictionary);
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
&lt;CFBasicHash 0x100108010 [0x7fff7b6bf110]>{type = immutable dict, count = 2,
entries =>
  0 : &lt;CFString 0x100001100 [0x7fff7b6bf110]>{contents = "key1"}
    = &lt;CFString 0x100001140 [0x7fff7b6bf110]>{contents = "value1"}
  1 : &lt;CFString 0x1000010e0 [0x7fff7b6bf110]>{contents = "key0"}
    = &lt;CFString 0x100001120 [0x7fff7b6bf110]>{contents = "value0"}
}
</pre>

<p>一行目を見ると、CFDictionaryのオブジェクトを作ったのにCFBasicHashと出力されました。
つまりCFDictionaryの実態はCFBasicHashだということになります。CFBasicHashはPrivateクラスなので通常、直接は使えません。そのためドキュメントにも記述はありませんが、名前にあるとおりハッシュテーブルを扱うCore Foundationのクラスです。辞書の実装方法はいろいろとあるようですが、CFDictionaryはハッシュテーブルで実装されています。</p>

<p><a href="http://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFDictionaryRef/Reference/reference.html">ドキュメント</a>にも</p>

<blockquote>
  <p>a dictionary uses a hash table to organise.</p>
  
  <p>整理するのにハッシュテーブルを使う</p>
</blockquote>

<p>と明記されています。</p>

<p>デバッグツールのInstrumentsを使っているとCFBasicHashをよく見かけますが、正体はこれです。</p>

<p><img src="https://dl.dropboxusercontent.com/u/89064/Screen%20Shot%202013-04-18%20at%2011.24.40%20PM.png" alt="Instruments" /></p>

<p>この実行結果の元となるアプリケーションでは、直接Core Foundationは使っていません。
それなのにCore Foundationのクラスがいくつも登場しています。このことから、Core Foundationが内部で多数使われているということが分かります。</p>

<p>CFBasicHashはCFDictionary以外でも使われていますので、後半のソースコードを見る章で扱います。
そもそもハッシュテーブルとは何かは、CFTypeのCFHashメソッドと関係するので、その時に扱います。</p>

<p>CFDictionaryCreateメソッドの引数</p>

<pre class="brush: objc; title: ; notranslate">
kCFTypeDictionaryKeyCallBacks
kCFTypeDictionaryValueCallBacks
</pre>

<p>は、CFArrayのときに使った</p>

<pre class="brush: objc; title: ; notranslate">
kCFTypeArrayCallBacks
</pre>

<p>と同じようなものです。</p>

<p>ためしに</p>

<pre class="brush: objc; title: ; notranslate">
dictionary = CFDictionaryCreate(kCFAllocatorDefault,
                                (const void**)keys,
                                (const void**)values,
                                2,
                                &#038;kCFTypeDictionaryKeyCallBacks,
                                NULL);
</pre>

<p>とKeyCallBacksだけ渡してみると</p>

<pre class="brush: objc; title: ; notranslate">
&lt;CFBasicHash 0x100108010 [0x7fff7b6bf110]>{type = immutable dict, count = 2,
entries =>
     0 : &lt;CFString 0x1000010f0 [0x7fff7b6bf110]>{contents = "key1"} = &lt;0x100001130>
     1 : &lt;CFString 0x1000010d0 [0x7fff7b6bf110]>{contents = "key0"} = &lt;0x100001110>
}
</pre>

<p>valueの値が出力されなくなります。</p>

<p>これは何が起こっているかといいうと、NSDictionaryを継承してdescriptionメソッドをオーバーライドしているのと同じことですね。
先に言っておくと、これはCore Foundationにおいて、メソッドオーバーライドに近い機能を実現するための仕組みです。
CFTypeの章のまとめで扱います。</p>

<p>もう一度、実行結果を見ると</p>

<pre class="brush: objc; title: ; notranslate">
entries =>
0 : &lt;CFString 0x100001100 [0x7fff7b6bf110]>{contents = "key1"} =
     &lt;CFString 0x100001140 [0x7fff7b6bf110]>{contents = "value1"}
1 : &lt;CFString 0x1000010e0 [0x7fff7b6bf110]>{contents = "key0"} =
     &lt;CFString 0x100001120 [0x7fff7b6bf110]>{contents = "value0"}
</pre>

<p>となっており、0, 1とエントリーに順番があるかのように見えますが、前述の通り順番を持っていませんので注意しましょう。もし順番に依存したコードを書いて特定の環境で上手く動作したとしても、他の環境での動かないでしょう。</p>

<p>key0, key1, value0, value1の順番を入れ替えて</p>

<pre class="brush: objc; title: ; notranslate">
const CFTypeRef keys[] = {CFSTR("key0"), CFSTR("key1")};
const CFTypeRef values[] = {CFSTR("value0"), CFSTR("value1")};
</pre>

<p>を</p>

<pre class="brush: objc; title: ; notranslate">
const CFTypeRef keys[] = {CFSTR("key1"), CFSTR("key1")};
const CFTypeRef values[] = {CFSTR("value1"), CFSTR("value0")};
</pre>

<p>としても、CFDictionaryのオブジェクトとしては同じものとなります。同じとはなにか、という話はCFEqualメソッドを扱うときに解説します。</p>

<h2>CFDate</h2>

<p>CFDateは日付を扱うクラスです。NSDateとToll-free bridging可能です。
CFDateCreateのドキュメントを見てみると</p>

<pre class="brush: objc; title: ; notranslate">
Creates a CFDate object given an absolute time.

CFDateRef CFDateCreate (
   CFAllocatorRef allocator,
   CFAbsoluteTime at
);
Parameters
at
The absolute time to convert to a CFDate object.
</pre>

<p>atには、absolute timeを渡す、とあります。</p>

<p>absolute timeは<strong>CFAbsoluteTimeGetCurrent</strong>関数を使って取得します。</p>

<pre class="brush: objc; title: ; notranslate">
CFAbsoluteTime CFAbsoluteTimeGetCurrent ();
</pre>

<p>Absolute timeは、ドキュメントを見ると</p>

<blockquote>
  <p>Absolute time is measured in seconds relative to the absolute reference date of Jan 1 2001 00:00:00 GMT. 
  2001/01 00:00:00 GMT(絶対基準)からの(相対)秒</p>
</blockquote>

<p>と書いてあります。実際にCFDateオブジェクトを作ってみましょう。</p>

<pre class="brush: objc; title: ; notranslate">
CFAbsoluteTime time = CFAbsoluteTimeGetCurrent();
printf("time = %f\n", time);
CFDateRef date = CFDateCreate(kCFAllocatorDefault, time);
CFShow(date);
time = CFDateGetAbsoluteTime(date);
printf("time = %f\n", time);

CFRelease(date);
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
time = 388368376.591624
2013-04-23 00:06:16 +0000
time = 388368376.591624
</pre>

<p>秒数からおよその日付を計算をしてみると</p>

<pre class="brush: objc; title: ; notranslate">
irb(main):001:0> 388368376 / (60 * 60 * 24)
=> 4495
irb(main):003:0> 4495 / 365.0
=> 12.315068493150685
</pre>

<p>12年と(12ヶ月 * 0.3) = 4ヶ月経過 
2001 + 12  + 4ヶ月 = 2013年4月 
なので合っています。Unix Timeの1970年始まりではないので注意しましょう。</p>

<p>日付の扱いは、CFLocale CFDateFormatterなど関係するクラスが他にもいくつかあります。
詳細は日付とロケールの章で扱います。</p>

<p>以上で基本クラスを簡単に使えるようになりました。
次回は基本クラスを対象に、CFTypeのメソッドを掘り下げます。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1746/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Hello, Core Foundation] 05 CFTypeとそのメソッド(4) コレクションクラス 準共通メソッド</title>
		<link>http://nagano.monalisa-au.org/archives/1701</link>
		<comments>http://nagano.monalisa-au.org/archives/1701#comments</comments>
		<pubDate>Mon, 22 Apr 2013 00:35:11 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Foundation]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1701</guid>
		<description><![CDATA[前回に引き続き、基本クラスを扱っていきます。 CFArrayとコレクションクラス CFArrayとCFMutableArrayは順番を持った値の集まりを扱うクラスです。 値の集まりを以降、コレクションと呼びます。 コレク [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://nagano.monalisa-au.org/archives/1630">前回</a>に引き続き、基本クラスを扱っていきます。</p>

<h2>CFArrayとコレクションクラス</h2>

<p>CFArrayとCFMutableArrayは順番を持った値の集まりを扱うクラスです。
値の集まりを以降、コレクションと呼びます。
コレクションを扱うクラスをコレクションクラスと呼びます。</p>

<p>Core Foundationには以下のコレクションクラスがあります</p>

<table>
<thead>
<tr>
  <th>クラス名</th>
  <th>概要</th>
</tr>
</thead>
<tbody>
<tr>
  <td>CFArray</td>
  <td>順番を持つ</td>
</tr>
<tr>
  <td>CFSet</td>
  <td>順番と重複を持たない</td>
</tr>
<tr>
  <td>CFDictionary</td>
  <td>KeyとValue</td>
</tr>
<tr>
  <td>CFBag</td>
  <td>順番持たない(重複可能)</td>
</tr>
<tr>
  <td>CFTree</td>
  <td>親と子関係を持つ。Mutable型無し</td>
</tr>
</tbody>
</table>

<p>コレクションクラスが扱う値とは何か、ということですが、FoundationのNSArrayは(NSObjectを継承したクラスの)オブジェクトだけを扱います。ドキュメントにも<strong>objects</strong>と記載があります。しかし、CFArrayのドキュメントにはCFTypeのオブジェクトでなければならない、という記述はありません。</p>

<p>CFArrayに限らず、Core Foundationのコレクションクラスは</p>

<p><a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFCollections/Articles/common.html">Collections Programming Topics for Core Foundation</a>
に</p>

<blockquote>
  <p>A collection can contain other Core Foundation objects, custom data structures, and primitive data values.<br />
  コレクションは、Core Foundationオブジェクト以外の独自のデータ構造、プリミティブ型も持つことができる。</p>
</blockquote>

<p>とあるように、<strong>CFTypeのオブジェクト以外も扱えます</strong>。</p>

<p>そのため、NSArrayのドキュメントでは対象は<strong>objects</strong>と書かれているのに対して、Core Foundationのドキュメントでは<strong>values</strong>と書かれています。</p>

<p>たとえば
CFArrayGetLastIndexOfValue
という最後のindexの値を返すメソッドの定義を見ると</p>

<pre class="brush: objc; title: ; notranslate">
CFIndex CFArrayGetLastIndexOfValue (
     CFArrayRef theArray,
     CFRange range,
     const void *value
     );
</pre>

<p>const void *value
となっています。</p>

<p>もし、CFTypeのオブジェクトのみを扱うのであれば</p>

<pre class="brush: objc; title: ; notranslate">
const CFTypeRef
</pre>

<p>となっているはずなのです。</p>

<p>NSArrayの</p>

<pre class="brush: objc; title: ; notranslate">
- (id)lastObject;
</pre>

<p>はid型を返すので、オブジェクトであることが明示されています。</p>

<p>以上の違いに注意しましょう。
しかし、CFTypeのオブジェクト以外を扱うにはいくつかの注意が必要です。
たとえばNSArrayのオブジェクトにToll-Free Bridgingしてdescriptionメソッドを呼ぶとクラッシュします。
ひとまず、続きはCFArrayの詳細を扱うことにして、ここでは簡単にCFTypeのオブジェクトのみを扱ってみます。</p>

<p>CFArrayはNSArrayとToll-Free Bridging可能です。iOS/MacでNSArrayを使わないアプリケーションはまずないと思うので、おなじみかと思います。
CFArrayも同様に、他のCore Foundationのクラスの戻り値、引数などでなにかと登場します。
まずは使ってみましょう。</p>

<pre class="brush: objc; title: ; notranslate">
const void *values[] = {CFSTR("A"),CFSTR("B"),CFSTR("C")};
CFArrayRef array = CFArrayCreate(kCFAllocatorDefault, values, 3, NULL);
CFShow(array);
CFRelease(array);
</pre>

<pre class="brush: objc; title: ; notranslate">
&lt;CFArray 0x100107ff0 [0x7fff7b6bf110]>{type = immutable, count = 3, values = (
0 : <0x100001080]]&gt;
1 : <0x1000010a0]]&gt;
2 : <0x1000010c0]]&gt;
)}
</pre>

<p>となりますが、CFStringがアドレス表示になっています。</p>

<pre class="brush: objc; title: ; notranslate">
0 : A
1 : B
2 : C
</pre>

<p>もしくは</p>

<pre class="brush: objc; title: ; notranslate">
A
B
C
</pre>

<p>と出力してほしいところです。</p>

<p>そこでドキュメントを見ると</p>

<pre class="brush: objc; title: ; notranslate">
CFArrayRef CFArrayCreate (
   CFAllocatorRef allocator,
   const void **values,
   CFIndex numValues,
   const CFArrayCallBacks *callBacks
);
</pre>

<p>引数、callBacksは</p>

<blockquote>
  <p>A pointer to a CFArrayCallBacks structure initialized with the callbacks for the array to use on each value in the collection.</p>
  
  <p>コレクションのそれぞれの値に対して使われるコールバック関数で初期化されたCFArrayCallBacks構造体のポインタ。</p>
  
  <p>This value may be NULL, which is treated as if a valid structure of version 0 with all fields NULL had been passed in.<br />
  NULLを渡すと、version = 0, それ以外はNULLの構造体を渡したとみなされる。</p>
  
  <p>If the collection contains only CFType objects, then pass a pointer to kCFTypeArrayCallBacks (<strong>&amp;kCFTypeArrayCallBacks</strong>) to use the default callback functions.<br />
  CFTypeオブジェクトのみを持つとき、kCFTypeArrayCallBacksのポインタを渡すとデフォルトのコールバック関数が使われる。</p>
</blockquote>

<p>とあります。そこでNULLではなくて、デフォルトのコールバック関数が使われるkCFTypeArrayCallBacksのポインタを渡してみます。</p>

<pre class="brush: objc; title: ; notranslate">
array = CFArrayCreate(kCFAllocatorDefault, values, 3, NULL);
</pre>

<p>を</p>

<pre class="brush: objc; title: ; notranslate">
array = CFArrayCreate(kCFAllocatorDefault, values, 3, &#038;kCFTypeArrayCallBacks);
</pre>

<p>とします。</p>

<p>すると出力が</p>

<pre class="brush: objc; title: ; notranslate">
(
    A,
    B,
    C
)
</pre>

<p>になります。これで伝統のプリントデバッグがはかどりそうです。
なぜこういう動作になるのかは、CFTypeのまだ登場していないメソッドが関係するので、CFTypeのメソッドまとめ編でやります。</p>

<p>Toll-Free Bridgingを使って</p>

<pre class="brush: objc; title: ; notranslate">
NSLog(@"%@", (__bridge NSArray*)array);
</pre>

<p>とすると同様に</p>

<pre class="brush: objc; title: ; notranslate">
(
    A,
    B,
    C
)
</pre>

<p>となります。</p>

<h2>CFMutableArray</h2>

<p>次はCFMutableArrayを使ってみましょう。
add,remove,atIndex,removeAllなど、配列処理でおなじみの処理が可能です。</p>

<pre class="brush: objc; title: ; notranslate">
CFMutableArrayRef array;
array = CFArrayCreateMutable(kCFAllocatorDefault,
                             0,
                             &#038;kCFTypeArrayCallBacks);
CFArrayAppendValue(array, CFSTR("A"));
CFArrayAppendValue(array, CFSTR("B"));
CFArrayAppendValue(array, CFSTR("C"));

CFShow(CFSTR("print all"));
CFShow(array);

CFArrayRemoveValueAtIndex(array, 1);
CFShow(CFSTR("RemoveValueAtIndex:1"));
CFShow(array);

CFArrayRemoveAllValues(array);
CFShow(CFSTR("RemoveAllValues"));
CFShow(array);

CFRelease(array);
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
print all
(
    A,
    B,
    C
)
RemoveValueAtIndex:1
(
    A,
    C
)
RemoveAllValues
(
)
</pre>

<h2>CFNumber</h2>

<p>CFNumberは数を扱うクラスです。
NSNumberと同じ、と考えておよそ問題ありませんが違いとしてはByteSize、TypeというCの数値型に&#8221;より近い&#8221;メソッドがあることです。たとえば<strong>CFNumberIsFloatType</strong>というメソッドがあります。</p>

<pre class="brush: objc; title: ; notranslate">
printf("CFIndex Value\n");
CFIndex value = 123;
CFNumberRef number;
number = CFNumberCreate(kCFAllocatorDefault,
                        kCFNumberCFIndexType,
                        &#038;value);
printf("numberType = %ld\n", CFNumberGetType(number));
printf("byteSize = %ld\n", CFNumberGetByteSize(number));
printf("isFloatType = %d\n", CFNumberIsFloatType(number));

NSInteger getValue;
CFNumberGetValue(number, kCFNumberCFIndexType , &#038;getValue);
printf("getValue = %ld\n", getValue);

printf("\nFloat Value\n");

float floatValue = 0.123;
CFNumberRef floatNumber;
floatNumber = CFNumberCreate(kCFAllocatorDefault,
                        kCFNumberFloatType,
                        &#038;floatValue);

printf("numberType = %ld\n", CFNumberGetType(floatNumber));
printf("byteSize = %ld\n", CFNumberGetByteSize(floatNumber));
printf("isFloatType = %d\n", CFNumberIsFloatType(floatNumber));

float getFloatValue;
CFNumberGetValue(floatNumber, kCFNumberFloatType, &#038;getFloatValue);
printf("getValue = %f\n", getFloatValue);

CFRelease(number);
CFRelease(floatNumber);
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
CFIndex Value
numberType = 4
byteSize = 8
isFloatType = 0
getValue = 123

Float Value
numberType = 5
byteSize = 4
isFloatType = 1
getValue = 0.123000
</pre>

<h2>CFBoolean</h2>

<p>CFBooleanはBoolean値を扱うクラスです。
ドキュメントを見ると、CFNumberを継承しているかと思いきや、していませんので注意しましょう。<br />
<strong>Derived from  CFPropertyList : CFType</strong></p>

<p>定義は少ししかありませんので、すべて見てみましょう。</p>

<pre class="brush: objc; title: ; notranslate">
typedef const struct__CFBoolean * CFBooleanRef;

CF_EXPORT
const CFBooleanRef kCFBooleanTrue;
CF_EXPORT
const CFBooleanRef kCFBooleanFalse;

CF_EXPORT
CFTypeID CFBooleanGetTypeID(void);

CF_EXPORT

Boolean CFBooleanGetValue(CFBooleanRef boolean);
</pre>

<p>Core Foundationのクラス群の中でも特殊で、create/copyメソッドがありません。
つまりCFBooleanを自分で作ることはできません。
それでも<strong>CFBooleanGetTypeID</strong>があることが重要です。同様のクラスにCFNullがあります。
TypeIDについては後ほど扱います。</p>

<p>次のコードでできることのほぼすべてです。</p>

<pre class="brush: objc; title: ; notranslate">
CFShow(kCFBooleanTrue);
CFShow(kCFBooleanFalse);

printf("true = %d\n", CFBooleanGetValue(kCFBooleanTrue));
printf("false = %d\n", CFBooleanGetValue(kCFBooleanFalse));
printf("CFBooleanGetTypeID = %ld\n", CFBooleanGetTypeID());
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
&lt;CFBoolean 0x7fff7b6bfa30 [0x7fff7b6bf110]>{value = true}
&lt;CFBoolean 0x7fff7b6bfa40 [0x7fff7b6bf110]>{value = false}
true = 1
false = 0
CFBooleanGetTypeID = 21
</pre>

<h2>CFNumberCompareメソッド</h2>

<p>比較メソッドであるCFNumberCompareを見ておきましょう。</p>

<pre class="brush: objc; title: ; notranslate">
CFComparisonResult CFNumberCompare (
   CFNumberRef number,
   CFNumberRef otherNumber,
   void *context
);
</pre>

<p>戻り値は小さい &lt; 、同じ = 、大きい > を表す以下の定数です。</p>

<pre class="brush: objc; title: ; notranslate">
typedefCF_ENUM(CFIndex, CFComparisonResult) {
    kCFCompareLessThan = -1L,
    kCFCompareEqualTo = 0,
    kCFCompareGreaterThan = 1
};
</pre>

<pre class="brush: objc; title: ; notranslate">
CFIndex one = 1, two = 2;
CFNumberRef number1, number2;
number1 = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &#038;one);
number2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &#038;two);

CFComparisonResult comparisonResult;
comparisonResult = CFNumberCompare(number1, number2, NULL);
printf("comparisonResult = %ld\n", comparisonResult);

comparisonResult = CFNumberCompare(number2, number2, NULL);
printf("comparisonResult = %ld\n", comparisonResult);

comparisonResult = CFNumberCompare(number2, number1, NULL);
printf("comparisonResult = %ld\n", comparisonResult); 

CFRelease(number1);
CFRelease(number2);
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
comparisonResult = -1
comparisonResult = 0
comparisonResult = 1
</pre>

<h2>CFBooleanの比較メソッド</h2>

<p>専用のメソッドはありません。
CFBooleanの比較は、まだ登場していませんが、CFEqualメソッドを使います。しかし行えるのは同じかの判定のみで、大小関係は判定できません。
また、そもそもオブジェクトは二個しかないので == 演算子を使っても同じことができます。</p>

<pre class="brush: objc; title: ; notranslate">
printf("kCFBooleanTrue : kCFBooleanFalse %d\n", CFEqual(kCFBooleanTrue, kCFBooleanFalse));
printf("kCFBooleanFalse : kCFBooleanFalse %d\n", CFEqual(kCFBooleanFalse, kCFBooleanFalse));
printf("kCFBooleanTrue : kCFBooleanTrue %d\n", CFEqual(kCFBooleanTrue, kCFBooleanTrue));

printf("kCFBooleanTrue : kCFBooleanFalse %d\n", kCFBooleanTrue == kCFBooleanFalse);
printf("kCFBooleanFalse : kCFBooleanFalse %d\n", kCFBooleanFalse == kCFBooleanFalse);
printf("kCFBooleanTrue : kCFBooleanTrue %d\n", kCFBooleanTrue == kCFBooleanTrue);
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
kCFBooleanTrue : kCFBooleanFalse  0
kCFBooleanFalse : kCFBooleanFalse  1
kCFBooleanTrue : kCFBooleanTrue  1
kCFBooleanTrue : kCFBooleanFalse  0
kCFBooleanFalse : kCFBooleanFalse  1
kCFBooleanTrue : kCFBooleanTrue  1
</pre>

<h2>CFStringCompare</h2>

<p>CFStringにもcompareがあります。</p>

<pre class="brush: objc; title: ; notranslate">
//kCFCompareLessThan
printf("a : b %ld\n", CFStringCompare(CFSTR("a"), CFSTR("b"), 0));

//kCFCompareEqualTo
printf("b : b %ld\n", CFStringCompare(CFSTR("b"), CFSTR("b"), 0));

//kCFCompareGreaterThan
printf("b : a %ld\n", CFStringCompare(CFSTR("b"), CFSTR("a"), 0));

// kCFCompareCaseInsensitive 大文字小文字を無視
printf("A : a %ld\n", CFStringCompare(CFSTR("A"), CFSTR("a"), kCFCompareCaseInsensitive));
</pre>

<p>実行結果</p>

<pre class="brush: objc; title: ; notranslate">
a : b -1
b : b 0
b : a 1
A : a 0
</pre>

<p>ドキュメントを見ると、compareOptionsには0を渡すとデフォルトの動作とあります。
オプションはいろいろありますが、大文字小文字を区別しない kCFCompareCaseInsensitive を使ってみました。結果、0 (== kCFCompareEqualTo)になっています。
文字列比較についてはCFStringの詳細で詳しく扱います。</p>

<h2>CFTypeに準共通のメソッド</h2>

<p>CFTypeには準共通のメソッドがある、と覚えておくとなにかと便利です。
簡単に言えば、いくつかのパターンがあり、Core Foundationが明確な規則によって作られていることが分かります。
Imutable型とMutable型を扱ったので、いくつかのメソッドを見てみると</p>

<p>CFArrayCreate<br />
CFArrayCreateCopy<br />
CFArrayCreateMutable<br />
CFArrayCreateMutableCopy</p>

<p>CFStringRef<br />
CFStringCreate(WithCString, WithBytes, &#8230;)<br />
CFStringCreateCopy<br />
CFStringCreateMutable<br />
CFStringCreateMutableCopy</p>

<p>のように、Mutable型を持つクラスはすべて</p>

<p>&#8220;ClassName&#8221; + Create (+ With**)<br />
&#8220;ClassName&#8221; + Create + Copy<br />
&#8220;ClassName&#8221; + Create + Mutable<br />
&#8220;ClassName&#8221; + Create + MutableCopy</p>

<p>というメソッドを必ず持っています。</p>

<p>それぞれ、NSObjectで言うところの、<strong>init</strong>、<strong>copy</strong>, <strong>mutableクラスのinitializeメソッド</strong>、<strong>mutableCopy</strong>、に該当します。
覚えておくとコーディングスピードが少し上がります。</p>

<p>Core Foundationでは、Mutable型を持つクラスは現在9つあります。</p>

<table>
<thead>
<tr>
  <th>Immutable型</th>
  <th>Mutable型</th>
</tr>
</thead>
<tbody>
<tr>
  <td>CFArray</td>
  <td>CFMutableArray</td>
</tr>
<tr>
  <td>CFAttributedString</td>
  <td>CFMutableAttributedString</td>
</tr>
<tr>
  <td>CFBag</td>
  <td>CFMutableBag</td>
</tr>
<tr>
  <td>CFBitVector</td>
  <td>CFMutableBitVector</td>
</tr>
<tr>
  <td>CFCharacterSet</td>
  <td>CFMutableCharacterSet</td>
</tr>
<tr>
  <td>CFData</td>
  <td>CFMutableData</td>
</tr>
<tr>
  <td>CFDictionary</td>
  <td>CFMutableDictionary</td>
</tr>
<tr>
  <td>CFSet</td>
  <td>CFMutableSet</td>
</tr>
<tr>
  <td>CFString</td>
  <td>CFMutableString</td>
</tr>
</tbody>
</table>

<h2>Compareメソッド</h2>

<p>大小関係があるクラス(CFString,CFNumber,CFDate)は
ClassName + Compare
という比較メソッドを持っています。</p>

<pre class="brush: objc; title: ; notranslate">
CFStringCompare
CFDateCompare
CFNumberCompare
</pre>

<p>戻り値はすべてCFComparisonResultです。</p>

<p>これはコレクションクラスを使うとソートが可能、ということです。
CFMutableArrayを使ってCFNumberをソートしてみましょう。</p>

<pre class="brush: objc; title: ; notranslate">
void CFArraySortValues (
   CFMutableArrayRef theArray,
   CFRange range,
   CFComparatorFunction comparator,
   void *context
);
</pre>

<p>第三引数のCFComparatorFunction comparatorには対象オブジェクトのcompareメソッド(の関数のポインタ)を渡します。</p>

<pre class="brush: objc; title: ; notranslate">
CFMutableArrayRef array;
array = CFArrayCreateMutable(kCFAllocatorDefault,
                             0,
                             &#038;kCFTypeArrayCallBacks);

CFIndex one = 1, two = 2, three = 3;
CFNumberRef number1, number2, number3;
number1 = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &#038;one);
number2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &#038;two);
number3 = CFNumberCreate(kCFAllocatorDefault, kCFNumberCFIndexType, &#038;three);

CFArrayAppendValue(array, number2);   
CFArrayAppendValue(array, number1);
CFArrayAppendValue(array, number3);

CFRelease(number1);
CFRelease(number2);
CFRelease(number3);


CFShow(CFSTR("print all"));
CFShow(array);

CFArraySortValues(array,
                  CFRangeMake(0, CFArrayGetCount(array)),
                  (CFComparatorFunction)CFNumberCompare,
                  NULL);

CFShow(CFSTR("sorted array"));
CFShow(array);

CFRelease(array);
</pre>

<pre class="brush: objc; title: ; notranslate">
print all
(
    2,
    1,
    3
)
sorted array
(
    1,
    2,
    3
)
</pre>

<p>ソートできました。</p>

<p>ちなみに、Foundationで同様の処理を書くと</p>

<p><pre class="brush: objc; title: ; notranslate">
NSMutableArray *array;
array = [NSMutableArray arrayWithArray:@[@2, @1,@3]];
[array sortUsingSelector:@selector(compare:)];
NSLog(@&quot;array = %@&quot;, array);
</pre></p>

<p>となります。
<a href="http://clang.llvm.org/docs/ObjectiveCLiterals.html">Clang 3.1からの新しいObjective-Cリテラル</a>とARCがいかに強力なのか分かります。</p>

<p>コレクションクラスとCompareは、CFEqual, CFHash,CFComparatorFunctionなどまだまだ関係するものがいくつかあるので後ほど登場します。</p>

<p>今回はCFArray, CFNumberを例にコレクションクラスの紹介と、Compareメソッドを使ってみました。次回は残りの基本クラスを扱います。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1701/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Hello, Core Foundation] 04 CFTypeとそのメソッド(3) 基本的なクラス群, Toll-Free Bridging, CFString</title>
		<link>http://nagano.monalisa-au.org/archives/1630</link>
		<comments>http://nagano.monalisa-au.org/archives/1630#comments</comments>
		<pubDate>Sun, 14 Apr 2013 23:59:24 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Foundation]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1630</guid>
		<description><![CDATA[前々回でdescriptionの出力、前回でメモリ管理をおぼえたので、オブジェクトを生成してdescriptionを表示する ということが、正しい作法でできるようになりました。 これからはいくつかのクラスを例に、CFTy [...]]]></description>
				<content:encoded><![CDATA[<p>前々回でdescriptionの出力、前回でメモリ管理をおぼえたので、オブジェクトを生成してdescriptionを表示する
ということが、正しい作法でできるようになりました。</p>

<p>これからはいくつかのクラスを例に、CFTypeの他のメソッドを理解していきましょう。
話を進めるには基本クラスを知っておく必要があるので、 先に簡単に見ていきましょう。</p>

<h2>基本クラスとは何か</h2>

<p>何をして基本というのか、よく使われるとか、これがないと成立しないとか、いろいろ定義はあると思いますが、本連載では、CFPropertyListを継承しているクラスを基本クラスと言うことにします。</p>

<p>第二回でCFStringのドキュメント見たときに<br />
<em>Derived from CFPropertyList Reference : CFType Reference</em><br />
という記述がされているのにCFPropertyList Referenceを後回しにしました。</p>

<p>実はこの記述は非常に重要で、CFPropertyListで扱えるクラスであることを表しています。
CFPropertyListはプロパティリストを扱うためのクラスです。
そして、CFPropertyListを使ってファイルに書き出しできるのは以下のクラス(のオブジェクト)だけなのです。</p>

<p><strong>CFData, CFString, CFArray, CFDictionary, CFDate, CFNumber(CFBoolean)</strong></p>

<p>これら基本クラスはCore Foundationで何かを行う際に頻出しますので、先に簡単に把握していきましょう。</p>

<h2>Toll-Free Bridging</h2>

<p>基本クラスとその機能を把握しやすくするために先に書いておくと、Core Foundationには<strong>Toll-Free Bridging</strong>という仕組みがあり、Core Foundationのオブジェクトのいくつかはキャストするだけで(！) Foundation.framework(以下、Foundation)のNS***というクラスのインスタンスとして使うことができます。基本クラスはすべてToll-Free Bridgeに対応しています(表参照)。</p>

<table>
<thead>
<tr>
  <th>Core Foundation (CF)</th>
  <th>Foundation (NS)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>CFData</td>
  <td>NSData</td>
</tr>
<tr>
  <td>CFString</td>
  <td>NSString</td>
</tr>
<tr>
  <td>CFArray</td>
  <td>NSArray</td>
</tr>
<tr>
  <td>CFDictionary</td>
  <td>NSDictionary</td>
</tr>
<tr>
  <td>CFDate</td>
  <td>NSDate</td>
</tr>
<tr>
  <td>CFNumber(CFBoolean)</td>
  <td>NSNumber</td>
</tr>
</tbody>
</table>

<p>たとえば、CFStringはNSStringとおよそ同じもの、と考えて大丈夫です(が、CFStringにしかないメソッドもあるのでこれが重要！)。
表の右側(Foundation)を見ると、iOS/Macの開発で頻繁に使うものばかりであることが分かります。<br />
Toll-Free BridgingはCore Foundationがなぜ存在するのか、ということに関わってくる重要な仕組みなので、後ほどじっくり扱います。</p>

<h2>Imutable型とMutable型</h2>

<p>CFNumber、CFDate以外には、それぞれ変更可能なMutable型が存在します。反対に変更不可能な型をImutable型といいます。</p>

<table>
<thead>
<tr>
  <th>Immutable型</th>
  <th>Mutable型</th>
</tr>
</thead>
<tbody>
<tr>
  <td>CFData</td>
  <td>CFMutableData</td>
</tr>
<tr>
  <td>CFString</td>
  <td>CFMutableString</td>
</tr>
<tr>
  <td>CFArray</td>
  <td>CFMutableArray</td>
</tr>
<tr>
  <td>CFDictionary</td>
  <td>CFMutableDictionary</td>
</tr>
<tr>
  <td>CFDate</td>
  <td>なし</td>
</tr>
<tr>
  <td>CFNumber(CFBoolean)</td>
  <td>なし</td>
</tr>
</tbody>
</table>

<p>Mutable型もToll-Free Bridgingに対応しています。機能もおよそ同等です。</p>

<table>
<thead>
<tr>
  <th>Core Foundation(CF)</th>
  <th>Foundation(NS)</th>
</tr>
</thead>
<tbody>
<tr>
  <td>CFMutableData</td>
  <td>NSMutableData</td>
</tr>
<tr>
  <td>CFMutableString</td>
  <td>NSMutableString</td>
</tr>
<tr>
  <td>CFMutableArray</td>
  <td>NSMutableArray</td>
</tr>
<tr>
  <td>CFMutableDictionary</td>
  <td>NSMutableDictionary</td>
</tr>
</tbody>
</table>

<p>CFMutable&#8221;ClassName&#8221;は、&#8221;ClassName&#8221;を継承している、とドキュメントにありますがこの連載では、単純にCFTypeを継承している、と書きます。</p>

<h2>CFString</h2>

<p>CFStringは文字列を扱うためのクラスです。</p>

<p>なんといってもCFSTRをよく使います。
CFSTRの注意点としては、retain/releaseが必須ではないことです。 
Foundationでも</p>

<pre class="brush: objc; title: ; notranslate">
NSString *string = @"String";
[string release];
</pre>

<p>とは書きません。これと同じです。
オブジェクトはアプリケーション終了時に開放されます。</p>

<p>もう一点、<a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFStrings/Articles/CreatingAndCopying.html">ドキュメント</a>を見ると</p>

<blockquote>
  <p>The argument of the macro must be a constant compile-time string—text enclosed in quotation marks.</p>
  
  <p>このマクロの引数はコンパイル時の定数文字列(&#8220;&#8221;で囲われたテキスト)でなければならない。</p>
</blockquote>

<p>とあります。それを強制している部分が面白いので見てみましょう。
まず、定義を見ると</p>

<pre class="brush: objc; title: ; notranslate">
#if TARGET_OS_WIN32 || TARGET_OS_LINUX
#undef __CONSTANT_CFSTRINGS__
#endif

#ifdef __CONSTANT_CFSTRINGS__
#define CFSTR(cStr)  ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))
#else
#define CFSTR(cStr)  __CFStringMakeConstantString("" cStr "")

#endif
</pre>

<p>(iOS/Mac環境では)TARGET_OS_WIN32 || TARGET_OS_LINUX は偽なので</p>

<div>__CONSTANT_CFSTRINGS__</div>

<p>はundefされていません。どこかで(ソースコードを見ると、CFInternal.hで！)定義されています。</p>

<p>そのためこのマクロが定義になります。</p>

<pre class="brush: objc; title: ; notranslate">
#define CFSTR(cStr)  ((CFStringRef) __builtin___CFStringMakeConstantString ("" cStr ""))  
</pre>

<pre class="brush: objc; title: ; notranslate">
__builtin___CFStringMakeConstantString
</pre>

<p>は</p>

<pre class="brush: objc; title: ; notranslate">
__builtin_  +  __CFStringMakeConstantString
</pre>

<p>に分解できます。<strong>__builtin_</strong> は関数をビルトイン関数化するGCCの拡張命令です。
<strong>__CFStringMakeConstantString</strong>は関数名です。<br />
<a href="https://github.com/opensource-apple/CF/blob/master/CFString.c#L1664">https://github.com/opensource-apple/CF/blob/master/CFString.c#L1664</a> に実装があります。</p>

<p>ビルトイン関数化すると、ドキュメントにはCの標準ライブラリ関数と同等になる、と書いてあります。最適化されたり、宣言がある.hファイルをインクルードしなくても使えるようになったりします(警告は出ますが)。
Core Foundationのソースコードの中でいくつか登場するので、連載後半のソースコードからCore Foundationを読み解く章で扱います。</p>

<p>たとえば、CFSTR(&#8220;yes&#8221;)と書いたとします。</p>

<p><pre class="brush: objc; title: ; notranslate">
&quot;&quot; &quot;yes&quot; &quot;&quot;
</pre></p>

<p>って何になるの？ということですが、両隣の&#8221;"を&#8221;A&#8221;だとしてみると</p>

<p>&#8220;A&#8221;"yes&#8221;"A&#8221;の途中にスペースがある書き方です。</p>

<pre class="brush: objc; title: ; notranslate">
printf("A" "yes" "A");
=> AyesA
</pre>

<p>つまり、&#8221;AyesA&#8221;と等価になります。こういう書き方ができるわけです。</p>

<p>たとえ</p>

<pre class="brush: objc; title: ; notranslate">
const char *cStr= "yes";
printf("A" cStr "A");
</pre>

<p>と書いたとしてもシンタックスエラーになるため、&#8221;"で囲われた文字列(文字列リテラル)を直接書くことしかできません。</p>

<pre class="brush: objc; title: ; notranslate">
"A""yes""A"
</pre>

<p>という書き方は応用すると、コード表記上、改行を入れたいときに便利です。</p>

<pre class="brush: objc; title: ; notranslate">
printf("A"
"yes"
"A");
</pre>

<p>と書くことができます。</p>

<p>同様の表記がNSStringでもできるので</p>

<pre class="brush: objc; title: ; notranslate">
NSLog(@"Core""Foundation");
NSLog(@"Core" "Foundation"); //この書き方は読み間違えるかもなのでよくなさそう
NSLog(@"Core"@"Foundation"); //これもOK
NSLog(@"Core"
      @"Foundation"); //これもOK
</pre>

<p>という書き方ができます。</p>

<p>次にCFShowStrを見ておきましょう。
CFStringの属性をログに出してくれるデバッグ用メソッドです。</p>

<pre class="brush: objc; title: ; notranslate">
CFShowStr
Prints the attributes of a string during debugging.
void CFShowStr (   CFStringRef str 
);
</pre>

<pre class="brush: objc; title: ; notranslate">
CFShow(CFSTR("yes"));
CFShowStr(CFSTR("yes"));
</pre>

<p>を実行すると</p>

<pre class="brush: objc; title: ; notranslate">
yes

Length 3
IsEightBit 1
HasLengthByte 0
HasNullByte 1
InlineContents 0
Allocator SystemDefault
Mutable 0
Contents 0x100000f70
</pre>

<p>という風に、CFStringの詳細を出力します。</p>

<p>注意点としては、デバッグ用なので、このメソッドが返す結果に依存したコードを書いてはいけません。
そういうコードを書いてしまうと、いつか動かなくなる可能性があります。Core FoundationもiOS/MacのSDKがバージョンアップするたびに変更が行われているからです。
これはCFShowも同様なので注意しましょう。</p>

<p>ドキュメントでは、デバッグ中にブレークポイントで止まっているときに</p>

<p><strong>(gdb) call (void) CFShowStr(string)</strong></p>

<p>と使う方法が紹介されています。</p>

<p>余談になりますが、CFSTRのドキュメントのRelated Sample Codeに注目すると、Core Audioばかり！</p>

<p>Related Sample Code</p>

<ul>
<li>AddMusic</li>
<li>iPhoneExtAudioFileConvertTest</li>
<li>iPhoneMixerEQGraphTest</li>
<li>iPhoneMultichannelMixerTest</li>
<li>SpeakHere</li>
</ul>

<p>つまり、Core Foundationの知識はCore Audioな人には必須ということになります。</p>

<h2>Core AudioとCore Foundation</h2>

<p>なぜCore AudioのサンプルコードでCore Foundationが使われているのか？
それは、Core AudioがC言語のインターフェイスを持つフレームワークだからです。Core AudioとCore Foundationを使えば、同じC言語だけで書くことができるため、相性がよいわけです。
Foundationが使われていれば、C++の世界に持っていくことができなくなります(Objective-C++には持っていけますが)。
Core Audioはハードウェアに近いフレームワークであるため、C++で実装されています。そのため、以前はほとんどのサンプルコードがC++で書かれていました。C++を好むプログラマはC, C++の世界で完結させたいのでFoundationではなくCore Foundationを使うわけです。
<a href="http://developer.apple.com/library/ios/#samplecode/SpeakHere/Listings/Classes_AQPlayer_h.html#//apple_ref/doc/uid/DTS40007802-Classes_AQPlayer_h-DontLinkElementID_11">SpeakHere</a>では、実際にCFStringをC++のクラスで使っています。
(Foundationを使うとNSAutoreleasePoolが必要になる、というのもあります)</p>

<p>iOS/Macで必要となる基本機能が(一番下の)C言語のレイヤーで実現されている、というのがCore Foundationの存在理由の一つなのです。
もっと付け加えるならば、Core Foundationはオープンソースなので(！！！)、iOS/Macとそれ以外の環境でのクロスプラットフォームなライブラリを作りたい場合、Core Foundationを使う、という選択肢があるでしょう。実際、Linuxで動く
Core Foundationがあるようです。
CFSTRマクロを見たときに</p>

<pre class="brush: objc; title: ; notranslate">
#if TARGET_OS_WIN32 || TARGET_OS_LINUX
</pre>

<p>という定義がありました。</p>

<p>また、これはWindows版Safariがあることと関係しています。
Windows版Safariのパッケージ内にCoreFoundation.dllというものがあり、これはCoreFoundation.frameworkと同等のものです。つまり、Core FoundationはWindowsでも動く、ということです。
また、<a href="https://github.com/markshiz/corefoundation-lite-android">Androidで動くCore Foundation</a>もあるようです。</p>

<p>Core Foundationのクラスは(特にメモリ管理、コレクションクラスにおいて)カスタマイズ性が考慮されており、ライブラリをごりっと書く、という用途が想定されているように思われます。この辺の仕組みはこの連載のハイライトになりそうな予感がしています。</p>

<p>CFStringを少し扱っただけで、いろいろなトピックが出てきてしまいました。
CFStringを理解することは、そのままC言語、そしてNSSringの理解へとつながり、それはiOS/Macの文字列処理を理解することとなります。そのため、後ほどじっくり扱います。</p>

<p>今回はCFStringを例に基本クラスの概要と余談を書きました。<br />
次回はその他の基本クラスを扱います。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1630/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Hello, Core Foundation] 03 CFTypeとそのメソッド(2) メモリ管理</title>
		<link>http://nagano.monalisa-au.org/archives/1586</link>
		<comments>http://nagano.monalisa-au.org/archives/1586#comments</comments>
		<pubDate>Fri, 05 Apr 2013 15:32:11 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Foundation]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1586</guid>
		<description><![CDATA[前回、CFTypeはCore Foundationのルートクラスであり、共通に使えるメソッドを持つことを説明しました。 そして、その中からCFShowを試しに使ってみました。 今回はメモリ管理に関するメソッド Memor [...]]]></description>
				<content:encoded><![CDATA[<p>前回、CFTypeはCore Foundationのルートクラスであり、共通に使えるメソッドを持つことを説明しました。<br />
そして、その中からCFShowを試しに使ってみました。</p>
<p>今回はメモリ管理に関するメソッド</p>
<p>Memory Management</p>
<ul>
<li>CFGetRetainCount</li>
<li>CFRelease</li>
<li>CFRetain</li>
</ul>
<p>を扱います。メモリ管理とは、メモリ領域の確保と破棄、ここではオブジェクトの生成と破棄のことです。<br />
CFTypeを継承するクラスすべてで必要になるため非常に重要です。<br />
この3つのメソッドと&#8221;Allocator&#8221; (あとで扱います)の解説のためだけに<br />
<a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFMemoryMgmt/CFMemoryMgmt.html" target="_blank">Memory Management Programming Guide for Core Foundation</a><br />
というドキュメントがあります。</p>
<p>おそらく実務上、Core Foundationで一番使うのはこのメソッド群です<br />
とくにCFReleaseはCore Foundationって何？という人も目にしたことがある可能性が高いと思います。</p>
<p>たとえば、CGPathRefを扱ったことがあれば</p>
<pre class="brush: objc; title: ; notranslate">
CGMutablePathRef path = CGPathCreateMutable();
...
CFRelease(path);
</pre>
<p>といったコードを書いたことがあると思います。</p>
<p>CGMutablePathRef? CFじゃないのに関係あるの？と思うかもしれませんが<br />
<a href="https://developer.apple.com/library/mac/#documentation/graphicsimaging/Reference/CGPath/Reference/reference.html" target="_blank">CGPathのドキュメント</a>を見ると<br />
<strong>Derived from  CFType Reference</strong><br />
と書いてあるのです。</p>
<p><a href="http://developer.apple.com/library/mac/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_overview/dq_overview.html" target="_blank">Quartz 2D Programming Guide: Overview of Quartz 2D </a>には</p>
<blockquote><p><strong>Quartz uses the Core Foundation memory management model, in which objects are reference counted. </strong><br />
QuartzはCore Foundationのリファレンスカウント方式のメモリ管理モデルを使う。</p></blockquote>
<p>と書いてあります。つまり、CFTypeのメモリ管理メソッドはCore Foundationだけにとどまらず、iOS/Macのいろいろなフレームワークで使うことになりますので、そこそこ複雑なアプリケーションを作る際には必須の知識です。</p>
<p>ちなみに、QuartzというiOS/Macの基礎(Foundation)を支えているフレームワークがCore Foundationを基礎としていることから、Core FoundationがまさにFoundationのCoreである、ことが分かります(まずはFoundation.frameworkを支えている、というのが正しいですが、この辺の話は後ほど)。</p>
<h2>リファレンスカウント方式のメモリ管理</h2>
<p>さて、もう「<strong>リファレンスカウント方式のメモリ管理</strong>」という言葉が出ましたが、Core Foundationはこの方式を使います。<br />
iOS/Macのアプリケーションを一個でも作ったことがあれば、同じ方式でメモリ管理を行ったことがあるはずなのです。<br />
リファレンスカウント方式のメモリ管理モデルというのは、Objective-Cの(NSObjectの)retain/releaseと同じ方式です。</p>
<p>先にこれから説明することをコードで見てみましょう。</p>
<pre class="brush: objc; title: ; notranslate">
NSObject *object = [[NSObject alloc] init]; //retain count = 1
[object retain]; //retain count = 2
[object release]; //retain count = 1
[object release]; //retain count = 0 開放される
</pre>
<p>(通常はこんなコードは書きませんが)<br />
と同じことを、Objective-Cのメッセージ式ではなく、C言語の関数で行うだけです。</p>
<p>CFTypeを作ることは(通常)できないので、CFStringで書くと</p>
<pre class="brush: objc; title: ; notranslate">
CFStringRef string;
string = CFStringCreateWithCString(kCFAllocatorDefault,
                                   &quot;Core Foundation&quot;,
                                   kCFStringEncodingUTF8);

printf(&quot;%ld\n&quot;,CFGetRetainCount(string)); //1

CFRetain(string);
printf(&quot;%ld\n&quot;,CFGetRetainCount(string)); //2

CFRelease(string);
printf(&quot;%ld\n&quot;,CFGetRetainCount(string)); //1

CFRelease(string); //0 開放される
</pre>
<p>となります。</p>
<p>Objective-Cの場合と同じですね。</p>
<h2>ルール</h2>
<p>Core Foundationのメモリ管理では、Objective-Cと同様のルールがあるので押さえておきましょう。<br />
<a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html" target="_blank">オーナーシップ・ルール</a>がCore Foundationにもあります。</p>
<p>3つを簡単に書くと</p>
<ol>
<li>オブジェクトを作ったらオーナーシップ(所有権)を持つ</li>
<li>どこかからゲットしたオブジェクトに対してはオーナーシップを持たない。ゲットした以降も使うならオーナーシップを持つ。
</li>
<li>オーナーシップを持ったら、必要なくなったときにオーナーシップを破棄する。</li>
</ol>
<p>となります。それぞれの文の主語はオブジェクトを使うオブジェクトです。<br />
オーナーシップを持つには、CFRetain、破棄するにはCFReleaseを使います。</p>
<p>また、1.の作るとはどういうことかというと、<a href="https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFMemoryMgmt/Concepts/Ownership.html#//apple_ref/doc/uid/20001148-103029" target="_blank">クリエイト・ルール</a>というものがあり</p>
<p>次の二つです。</p>
<ol>
<li>メソッドにCreateという文字があったら、オーナーシップを持つ</li>
<li>メソッドにCopyという文字があったら、オーナーシップを持つ</li>
</ol>
<p>Objective-Cでは、copy, mutableCopy, new, init**というメソッドはretainCountが1のインスタンスを返すというルールがありますが、これと同等のものです。<br />
たとえば、サンプルコードの<br />
CFStringCreateWithCString<br />
がこれにあたります。</p>
<h2>ルールのまとめ</h2>
<p>以上を簡単にまとめると</p>
<ol>
<li>CreateもしくはCopyという名前がついたメソッドでオブジェクトを作ったら、必ず対でCFReleaseする。</li>
<li>Copy/Createじゃないメソッドでオブジェクトをゲットしたら、何もしない。</li>
<li>ただし、2.でゲットしたオブジェクトが無くなるとまずい場合はCFRetainする。その場合、必要なくなったらCFReleaseする。</li>
</ol>
<p>以上のルールも、Objective-Cのメモリ管理とほぼ同じですね。<br />
これは偶然ではなくて、Objective-Cで使うNSObjectとCFTypeはじつは双子みたいなものなのです。<br />
その辺の話も後ほど。</p>
<h2>Core FoundationとARC</h2>
<p>NSObjectのretainとreleaseをサンプルコードで書きましたが、今はARC時代。もう書きませんよね。</p>
<p>ですが、Core Foundationは現在ARCに対応していないのでCFRetain/CFReleaseを自分で書く必要があります。<br />
ARCとCore Foundationのメモリ管理の関係、Objective-Cのメモリ管理については<br />
<a href="http://www.amazon.co.jp/dp/4844331094?tag=monalisaauorg-22" target="_blank">「エキスパートObjective-Cプログラミング」</a><br />
が非常に詳しいです。<br />
少々難しいですが、iOS/Macのアプリケーションを開発するなら必ず必要になる大事な部分なので、二ヶ月ぐらいかけてもいいので読みましょう。</p>
<p><iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=monalisaauorg-22&#038;o=9&#038;p=8&#038;l=as1&#038;asins=4844331094&#038;ref=tf_til&#038;fc1=000000&#038;IS2=1&#038;lt1=_blank&#038;m=amazon&#038;lc1=0000FF&#038;bc1=000000&#038;bg1=FFFFFF&#038;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<p>次回はこの先を説明するために、Core Foundationの基本的なクラスをいくつか紹介します。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1586/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MOSA Software Meeting 2012「Audio Unitの世界」セッションビデオ 発売</title>
		<link>http://nagano.monalisa-au.org/archives/1566</link>
		<comments>http://nagano.monalisa-au.org/archives/1566#comments</comments>
		<pubDate>Wed, 27 Mar 2013 05:26:50 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Codex]]></category>
		<category><![CDATA[Core Audio]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1566</guid>
		<description><![CDATA[MOSA Software Meeting2012 で「Audio Unitの世界」というセッションをやったのですが そのビデオが発売になっています。 Audio Unitでサイン波を鳴らす初歩から、AUGraphでEf [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://www.mosa.gr.jp/?p=9038" target="_blank"><br />
<img src="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-03-27-at-2.13.49-PM.png" width="500" height="277"/><br />
</a></p>
<p>MOSA Software Meeting2012<br />
で<a href="http://www.mosa.gr.jp/?p=6641&#038;page=2#nagano" target="_blank">「Audio Unitの世界」というセッション</a>をやったのですが<br />
<a href="http://www.mosa.gr.jp/?p=9038" target="_blank">そのビデオが発売になっています</a>。</p>
<p>Audio Unitでサイン波を鳴らす初歩から、AUGraphでEffectを使うのあと、Sampler Unitを使ってドラムマシンを作るところまで解説しています。<br />
ビデオの他に、キーノートと以下のような資料(39ページのPDFファイル)も付いています！<br />
<a href="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-03-28-at-1.53.16-AM.png"><img src="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-03-28-at-1.53.16-AM.png" alt="Screen Shot 2013-03-28 at 1.53.16 AM" width="591" height="527" /></a></p>
<p>買ってください。</p>
<p><strong>セミナーの内容</strong><br />
■概要<br />
ソフトウェア、ハードウェアの進化によってiPhoneはポケットの中の音楽スタジオと言っても過言ではないほど、パワフルなオーディオ処理環境となっています。特にiOS 5から多くのAudio Unit(エフェクト、サンプラー機能)が追加されたことは見逃せません。<br />
このセッションでは、これらのAudio Unitの使い方と簡単なサンプラーの開発方法をデモを交えながら解説しています。</p>
<p>■対象者（技術レベル）<br />
・簡単なiOSアプリケーションをApp Storeでリリースする程度の開発経験がある方<br />
・C言語およびObjective-Cの知識がある方<br />
・AVFoundationを使って、録音・再生機能を実現できる方<br />
(Audio Unitを使ったことがあるほうが望ましいですが、最初に簡単に解説します)</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1566/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Hello, Core Foundation] 02 CFTypeとそのメソッド(1) 概要</title>
		<link>http://nagano.monalisa-au.org/archives/1516</link>
		<comments>http://nagano.monalisa-au.org/archives/1516#comments</comments>
		<pubDate>Sun, 24 Mar 2013 13:08:38 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Foundation]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1516</guid>
		<description><![CDATA[前回、CFSTRという関数(実装はマクロ)が出てきたので、それから見ていきます。 ドキュメントを見ると Creates an immutable string from a constant compile-time s [...]]]></description>
				<content:encoded><![CDATA[<p>前回、CFSTRという関数(実装はマクロ)が出てきたので、それから見ていきます。<br />
<a href="https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html#//apple_ref/c/macro/CFSTR">ドキュメント</a>を見ると</p>
<p>Creates an immutable string from a constant compile-time string.</p>
<pre class="brush: objc; title: ; notranslate">
CFStringRef CFSTR (const char *cStr);
</pre>
<p>となっています。戻り値はCFStringRefです。</p>
<p>CFStringRefは文字列を扱うものですが<br />
まずは<a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFStringRef/Reference/reference.html">ドキュメント</a>を見ます。</p>
<p><a href="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-03-24-at-10.32.38-PM.png"><img src="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-03-24-at-10.32.38-PM.png" alt="Screen Shot 2013-03-24 at 10.32.38 PM" width="484" height="148" class="aligncenter size-full wp-image-1549" /></a></p>
<p><em>Derived from  CFPropertyList Reference : CFType Reference</em><br />
と書いてあります。</p>
<p>Derived from なので、CFPropertyListとCFTypeから派生しているということですね。<br />
<a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFPropertyListRef/Reference/reference.html">CFPropertyListのドキュメント</a>を見ると<br />
<em>Derived from CFType</em><br />
と書いてあります。<br />
以上からCFStringRefは、CFTypeを継承していることが分かります。</p>
<p>CFPropertyListも重要なのですが、ここでは先にCFTypeにフォーカスします。</p>
<h2>CFType</h2>
<p><a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html" target="_blank">CFTypeのドキュメント</a>を見ると<br />
Derived from  None</p>
<p>その下のOverviewを見ると</p>
<blockquote><p>All other Core Foundation opaque types derive from CFType.</p></blockquote>
<blockquote><p>CFTypeを除くすべてのCore Foundationの不透過型はCFTypeから派生している</p></blockquote>
<p>と書いてあります。つまり、CFTypeがオブジェクト指向言語で言うところのルートクラスです。<br />
ただ、CFTypeのドキュメントを見ると、一言も&#8221;クラス&#8221;とは書いてないことに注意しておきましょう。<br />
メソッド、インスタンス変数という言葉も出てきません。<br />
書いてあるのは、<strong>opaque type(不透過型)</strong>だけです。</p>
<h2>opaque type 不透過型</h2>
<p>不透過型というのは、たとえば、CFStringRefの定義を見ると</p>
<pre class="brush: objc; title: ; notranslate">
typedef const struct __CFString * CFStringRef; 
</pre>
<p>とあるのですが、構造体__CFStringの定義はどこにもなく、隠されています。<br />
そのため、構造体のメンバーを直接変更することが(やろうと思えばできるけど、一応)出来なくなっており、メンバーをもし変更可能としたいなら、たとえばset/get用の関数を別途用意することで、オブジェクト指向で言うところのカプセル化を実現することができるのです。</p>
<p>このパターンはiOS/MacのC言語のインターフェイスを持つフレームワークで頻出します。<br />
Core Audioでもよく使われます。たとえばAudioUnit型はOpaqueAudioComponentのポインタ型でOpaqueAudioComponentという構造体の定義は隠されています。</p>
<p>CFTypeに話を戻すと<br />
<a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFDesignConcepts/Articles/PolymorphicFunctions.html" target="_blank">Core Foundation Design Concepts: Polymorphic Functions </a></p>
<p>に次のような一文があります。</p>
<blockquote><p>CFType is analogous to a root class in object-oriented languages because its functions can be reused by all other objects.<br />
CFTypeはオブジェクト指向言語のルートクラスに似ている。その関数は他のすべてのオブジェクトで再利用できるからだ。</p></blockquote>
<p>なので、厳密にはCFTypeはルート&#8221;クラス&#8221;ではないのですが、そう考えた方が分かりやすいです。<br />
そのため、以降この連載ではCFTypeはルートクラスであると見なします。<br />
同時に、そこから派生した不透過型もクラスと見なします。<br />
たとえば</p>
<p><em>CFStringRefはCFTypeRefを継承したクラス</em></p>
<p>というような記述をします。</p>
<p>クラスと見なすのですから、不透過型を引数に取る関数も、メソッドと呼んだほうがいいでしょう。</p>
<p><em>CFStringRefのメソッド、CFStringCompareは、文字列同士を比較します</em></p>
<p>というような記述をします。</p>
<h2>CFTypeのメソッド</h2>
<p>CFTypeは</p>
<p>先ほどの一文に</p>
<blockquote><p>その関数は他のすべてのオブジェクトで再利用できるからだ。</p></blockquote>
<p>とあるように、Core Foundationのオブジェクトすべてで使用できる重要なメソッドを持っています。</p>
<p>Memory Management<br />
   * CFGetAllocator<br />
   * CFGetRetainCount<br />
   * CFMakeCollectable<br />
   * CFRelease<br />
   * CFRetain</p>
<p>Determining Equality<br />
   * CFEqual</p>
<p>Hashing<br />
   * CFHash</p>
<p>Miscellaneous Functions<br />
   * CFCopyDescription<br />
   * CFCopyTypeIDDescription<br />
   * CFGetTypeID<br />
   * CFShow</p>
<p>CFMakeCollectableは(廃止予定の)ガーベージコレクション関係のメソッドなので除外すると、以上、10個のメソッドがあります。</p>
<p>前回も使ったCFShowが、本当にすべてのCore Foundationオブジェクトに対応できるのか試してみましょう。CFStringRefとCFArrayRefのインスタンスを渡してみます。</p>
<p><script src="https://gist.github.com/7gano/5231806.js"></script></p>
<p>できていますね。<br />
次回はその他のメソッドを見ていきましょう。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1516/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[Hello, Core Foundation] 01 導入</title>
		<link>http://nagano.monalisa-au.org/archives/1466</link>
		<comments>http://nagano.monalisa-au.org/archives/1466#comments</comments>
		<pubDate>Wed, 20 Mar 2013 12:48:34 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Foundation]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1466</guid>
		<description><![CDATA[ふと、Core Foundationって面白そうだなーと思い、困らない程度には知っているけど、深くは知らないし、Foundation Frameworkに無い便利クラスがあるとは知っているけど使ったこと無いものも多い。で [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-03-20-at-9.38.30-PM.png"><img src="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-03-20-at-9.38.30-PM.png" alt="Screen Shot 2013-03-20 at 9.38.30 PM" width="530" height="399" class="aligncenter size-full wp-image-1493" /></a></p>
<p>ふと、Core Foundationって面白そうだなーと思い、困らない程度には知っているけど、深くは知らないし、Foundation Frameworkに無い便利クラスがあるとは知っているけど使ったこと無いものも多い。ではBlogでも書いてみよう、と思い始め調べはじめました。<br />
そこで、Core Foundationとその周辺の話を書いていきます。</p>
<p>見通しとしては</p>
<ul>
<li>CFTypeRef周りで数回</li>
<li>Core Foundationは現在、約45個のクラスがあるので、それぞれのクラスを扱うと45回</li>
<li>CFNetwork.frameworkというのが居るので10回ぐらい</li>
<li>Quartz 2D(Core Graphics)のオブジェクトモデルがCore Foundation Object形式なので、その辺をやると数回</li>
</ul>
<p>の計70回ぐらいの連載になって、数年やっても終わらないと思います。</p>
<h2>Core Foundationを理解するメリットはなにか</h2>
<p>僕も詳しくないのであれですが、現段階で言えることは以下</p>
<ul>
<li>iOSの開発でCF****(たとえばCFError)とか出てくるので、何かNS***じゃないものがあるのは知っているけど、よく分かっていない人は、その辺の事情が分かってDebugとかが捗るかも</li>
<li>Quartz 2Dをやる人はCGPathRefとかをCFReleaseしたことがあると思いますが、これが何なのか分かる(その他CFTypeRefを継承したオブジェクトが基本のフレームワークが多数ある)</li>
<li>何かの機能を実現したいとき、これ簡単にできないのかなー、と思ってNS***とかを調べて無かったら自作していた人は、CF***も調べるようになって、その機能が見つかるかも</li>
</ul>
<p>さて、何かを調べ始めるとしたらまずはAppleのドキュメントを読むでしょう。</p>
<p>最初に読むのは<br />
<a href="https://developer.apple.com/library/mac/#documentation/CoreFoundation/Conceptual/CFDesignConcepts/CFDesignConcepts.html">Core Foundation Design Concepts</a><br />
でしょう。</p>
<p>あとは、コンパイル、実行する環境を作ります。<br />
Xcodeで、ずばりCore Foundationというテンプレートがあるのでこれを使います。<br />
iOSじゃなくてOS X Applicationの方を選びます。<br />
<a href="http://nagano.monalisa-au.org/wp-content/uploads/12.png"><img src="http://nagano.monalisa-au.org/wp-content/uploads/12.png" alt="1" width="500" height="333" class="aligncenter size-full wp-image-1481" /></a></p>
<p>次にTypeでCore Foundationを選びます。<br />
<a href="http://nagano.monalisa-au.org/wp-content/uploads/23.png"><img src="http://nagano.monalisa-au.org/wp-content/uploads/23.png" alt="2" width="500" height="334" class="aligncenter size-full wp-image-1486" /></a></p>
<p>NS***を使いたいときもあるし、Foundationの方が何かと捗りますが、Core Foundationで一回プロジェクトを作ってみます。</p>
<p>次はHello, Worldしたくなると思うのでやってみましょう。</p>
<p>Core Foundationでプロジェクトを作ると、もうできています。<br />
⌘ + Rしてください。iOSと違ってシミュレーターの起動とか無いので一瞬です。</p>
<p><a href="http://nagano.monalisa-au.org/wp-content/uploads/43.png"><img src="http://nagano.monalisa-au.org/wp-content/uploads/43.png" alt="4" width="631" height="392" class="aligncenter size-full wp-image-1476" /></a></p>
<p>みたいにHello, Worldと出れば成功です。</p>
<p>プロジェクトを眺めると見るべきものはmain.cぐらいしかありません。<br />
main.cってことは、これObjective-Cは全然関係ないですね。.cなのでPure Cです。<br />
もう一回言うとObjective-Cは全然関係ありません。</p>
<p>興味があるのはこの一行です。</p>
<pre class="brush: objc; title: ; notranslate">
CFShow(CFSTR(&quot;Hello, World!\n&quot;));
</pre>
<p>CFShowは</p>
<pre class="brush: objc; title: ; notranslate">
void CFShow(CFTypeRef obj);
</pre>
<p>となっていて、<a href="https://developer.apple.com/library/mac/documentation/CoreFoundation/Reference/CFTypeRef/Reference/reference.html#//apple_ref/c/func/CFShow">ドキュメントを見ると</a><br />
Prints a description of a Core Foundation object to stderr.<br />
と書いてあります。<br />
&#8220;Core Foundation object&#8221;<br />
という用語が出ました。</p>
<p>ということは、CFSTRでCore Foundation objectが作られて、それのdescriptionがHello, World!だということですね。<br />
引数はCFTypeRef型なのでCFTypeRefがCore Foundation Object型っぽいですね。</p>
<p>今回は導入編なのでこれぐらいにして、次回からCore Foundation Objectって何？とかやっていきます。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1466/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>2013/02/23 13:15~14:00 『けっこーすごいよ、Audio Unit』at conferenceWithDevelopers</title>
		<link>http://nagano.monalisa-au.org/archives/1441</link>
		<comments>http://nagano.monalisa-au.org/archives/1441#comments</comments>
		<pubDate>Mon, 11 Feb 2013 12:47:29 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Audio]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1441</guid>
		<description><![CDATA[conferenceWithDevelopers というiOSデベロッパーのカンファレンスで一個セッションをやります conferenceWithDevelopersはiOS開発に携わる、すべての開発者に向けたカンファレ [...]]]></description>
				<content:encoded><![CDATA[<p><a href="http://nagano.monalisa-au.org/?attachment_id=1443" rel="attachment wp-att-1443"><img src="http://nagano.monalisa-au.org/wp-content/uploads/Screen-Shot-2013-02-11-at-9.37.50-PM.png" alt="Screen Shot 2013-02-11 at 9.37.50 PM" width="589" height="160" class="aligncenter size-full wp-image-1443" /></a><br />
<a href="http://conference-with-developers.info/">conferenceWithDevelopers</a></p>
<p>というiOSデベロッパーのカンファレンスで一個セッションをやります</p>
<blockquote><p>
conferenceWithDevelopersはiOS開発に携わる、すべての開発者に向けたカンファレンスイベントです。 登壇者によるiOSにまつわる技術トークとエンジニアの交流をメインの目的としています。</p></blockquote>
<p>僕は<br />
<strong><a href="http://conference-with-developers.info/session.html ">13:15~14:00『けっこーすごいよ、Audio Unit』</a></strong><br />
というセッションで、Audio Unitを使って、何か楽器っぽいものを作る方法を解説します。<br />
iOS 5以降の新しい話なので、Core Audio本には載っていない内容になります。</p>
<p>無料のイベントでまだ空きがあるみたいなので、興味がある方はおこしください。</p>
<p>そういえば、Core Audio本は売り切れたみたいです。<br />
改訂の予定は今のところありませんし、増刷もしないみたいなので、欲しい方は本屋で見つけたら買っておいた方がいいと思います。<br />
今、Amazonだと1万円ぐらいしますね。</p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1441/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>【夜間/中級】iOS開発セミナー： iOS6時代のCore Audioの基礎</title>
		<link>http://nagano.monalisa-au.org/archives/1419</link>
		<comments>http://nagano.monalisa-au.org/archives/1419#comments</comments>
		<pubDate>Fri, 28 Sep 2012 05:35:54 +0000</pubDate>
		<dc:creator>Norihisa Nagano</dc:creator>
				<category><![CDATA[Core Audio]]></category>

		<guid isPermaLink="false">http://nagano.monalisa-au.org/?p=1419</guid>
		<description><![CDATA[iOS 6、iPhone 5が出たりと、騒がしい昨今ですが セミナーのお知らせです。 【夜間/中級】iOS開発セミナー： iOS6時代のCore Audioの基礎 前回、前々回のセミナー 「iPhone Core Aud [...]]]></description>
				<content:encoded><![CDATA[<p>iOS 6、iPhone 5が出たりと、騒がしい昨今ですが<br />
セミナーのお知らせです。</p>
<p><a href="http://www.mosa.gr.jp/?p=5359">【夜間/中級】iOS開発セミナー： iOS6時代のCore Audioの基礎</a></p>
<p><a href="http://www.mosa.gr.jp/?p=5359"><img src="http://nagano.monalisa-au.org/wp-content/uploads/IMG_3642.png" width="320" height="568" class="alignnone size-full wp-image-1423" /></a></p>
<p>前回、前々回のセミナー<br />
<a href="http://www.mosa.gr.jp/?p=3398">「iPhone Core Audio入門セミナー：Core Audioの概要から”ボイスメモ”アプリケーションの作成まで」</a><br />
<a href="http://www.mosa.gr.jp/?p=3807">「iPhone Core Audio入門セミナー：波形編集アプリを作ろう」</a></p>
<p>が好評いただけたようで<br />
またまた続編をやらせていただくことになりました。<br />
続編とはいいつつも今回は<br />
iOS 6が出て、Core Audioも進化してきているので<br />
基礎編を更新したものがやりたいなと思っていました。<br />
そこで<br />
「iOS6時代のCore Audioの基礎」<br />
ということで、Core Audioの全容を話させてもらいます。</p>
<p>Core Audio本と同じく、Core Audioの全容をシンプルなサンプルコードをベースに解説していきます。<br />
その中でiOS 6までに増えたフレームワーク、APIなどを一緒に説明していきます。<br />
iOS 5でかなり機能が増えたので、そこが中心になると思います。</p>
<p>対象者は<br />
・簡単なiPhoneアプリケーションを作成したことがある方<br />
・C言語およびObjective-Cの知識がある方<br />
です。</p>
<p>有料ですが、ぜひお越しください。</p>
<h4>日 時：2012年10月26日（金）18：30～21：30（休憩含む）</h4>
<h4>会 場：大橋会館 （東京都目黒区）</h4>
<h4>地下鉄田園都市線「池尻大橋」駅下車（渋谷駅より１つ目）。東口から駅前商店街を直進。徒歩約5分。</h4>
<h4>主 催：特定非営利活動法人MOSA</h4>
<p><a href="http://www.mosa.gr.jp/?p=5359">http://www.mosa.gr.jp/?p=5359</a></p>
]]></content:encoded>
			<wfw:commentRss>http://nagano.monalisa-au.org/archives/1419/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
