CoreDataにストアしてあるデータをTableViewでセクションとインデックス付きで表示する際,CoreDataからセクション名を取得する方法があります。
私が作っているアプリは主に電車の時刻表を扱うので,始発から終電までの発車時刻を並べて表示しています。その際,1時間毎にセクションにまとめて表示します。
セクション名は,始発が朝5時で終電が夜中1時まであれば,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,0,1という順番になることを意図しています(最後の方が24時,25時でなく0時,1時ってところがミソです)。
最後の0,1は最初の5,6...よりも小さい数字ですが,データ取得する際のソート指定において内部的に24,26になるようにしてあるわけです。
--
さて,
セクション名を取得する方法としてNSFetchedResultsControllerに対してsectionsメソッドでセクションの集合を取り出し,ひとつひとつセクションを取り出して名前を取得していました。
iPhone OS3.1.3までは,この方法で意図した順番にセクション名を取得できました。ところがiOS4上では,全く同じプログラムなのに取得されたセクション名の並び順が0,1,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23となってしまう挙動に変わってしまっています。
最初は開発環境の変化で,諸々の設定が適切でなくなったせいなのかと,あれこれ設定を変えてみたのですが,現象に変化はなし。シミュレーターでも実機でもiPhone OS3.1.3では従来通り意図通り動作しているのですが,iOS4では並びが変わってしまいます。
--
■実験
とにかく実験してみましょう...
○取得方法その1:セクション自体の集合を取得してひとつずつ名前を取り出す
NSArray* fetchedTitles1 = [fetchedResultsController sections];
for (id section in fetchedTitles1) {
NSLog(@"Sec %@",[section name]);
}
○取得方法その2:セクション名の配列を取得して名前を取り出す
NSArray* fetchedTitles2 = [fetchedResultsController sectionIndexTitles];
for (NSString *secname in fetchedTitles2) {
NSLog(@"SecNm: %@",secname);
}
取得方法その2は,1文字しか取得してくれないので,10番台は「1」20番台は「2」にまとめられて表示されます。
なお,今回の実験のデータは終電が0時台の時刻表を使用したので,0時だけが注目点になります。
■結果
【iPhone3G + iPhone OS3.1.3】意図した並び...
○取得方法その1
2010-07-17 03:52:31.996 RideOnTime[78:207] Sec 5
2010-07-17 03:52:32.002 RideOnTime[78:207] Sec 6
2010-07-17 03:52:32.007 RideOnTime[78:207] Sec 7
2010-07-17 03:52:32.013 RideOnTime[78:207] Sec 8
2010-07-17 03:52:32.019 RideOnTime[78:207] Sec 9
2010-07-17 03:52:32.024 RideOnTime[78:207] Sec 10
2010-07-17 03:52:32.030 RideOnTime[78:207] Sec 11
2010-07-17 03:52:32.044 RideOnTime[78:207] Sec 12
2010-07-17 03:52:32.050 RideOnTime[78:207] Sec 13
2010-07-17 03:52:32.055 RideOnTime[78:207] Sec 14
2010-07-17 03:52:32.060 RideOnTime[78:207] Sec 15
2010-07-17 03:52:32.065 RideOnTime[78:207] Sec 16
2010-07-17 03:52:32.071 RideOnTime[78:207] Sec 17
2010-07-17 03:52:32.077 RideOnTime[78:207] Sec 18
2010-07-17 03:52:32.083 RideOnTime[78:207] Sec 19
2010-07-17 03:52:32.089 RideOnTime[78:207] Sec 20
2010-07-17 03:52:32.094 RideOnTime[78:207] Sec 21
2010-07-17 03:52:32.099 RideOnTime[78:207] Sec 22
2010-07-17 03:52:32.156 RideOnTime[78:207] Sec 23
2010-07-17 03:52:32.167 RideOnTime[78:207] Sec 0
○取得方法その2
2010-07-17 03:52:38.298 RideOnTime[78:207] SecNm: 5
2010-07-17 03:52:38.305 RideOnTime[78:207] SecNm: 6
2010-07-17 03:52:38.310 RideOnTime[78:207] SecNm: 7
2010-07-17 03:52:38.316 RideOnTime[78:207] SecNm: 8
2010-07-17 03:52:38.321 RideOnTime[78:207] SecNm: 9
2010-07-17 03:52:38.326 RideOnTime[78:207] SecNm: 1
2010-07-17 03:52:38.331 RideOnTime[78:207] SecNm: 2
2010-07-17 03:52:38.338 RideOnTime[78:207] SecNm: 0
【iPhone3GS + iOS4】意図せざる並び...
○取得方法その1
2010-07-17 03:48:12.698 RideOnTime[497:307] Sec 0
2010-07-17 03:48:12.702 RideOnTime[497:307] Sec 5
2010-07-17 03:48:12.708 RideOnTime[497:307] Sec 6
2010-07-17 03:48:12.713 RideOnTime[497:307] Sec 7
2010-07-17 03:48:12.718 RideOnTime[497:307] Sec 8
2010-07-17 03:48:12.723 RideOnTime[497:307] Sec 9
2010-07-17 03:48:12.729 RideOnTime[497:307] Sec 10
2010-07-17 03:48:12.734 RideOnTime[497:307] Sec 11
2010-07-17 03:48:12.739 RideOnTime[497:307] Sec 12
2010-07-17 03:48:12.744 RideOnTime[497:307] Sec 13
2010-07-17 03:48:12.749 RideOnTime[497:307] Sec 14
2010-07-17 03:48:12.754 RideOnTime[497:307] Sec 15
2010-07-17 03:48:12.760 RideOnTime[497:307] Sec 16
2010-07-17 03:48:12.765 RideOnTime[497:307] Sec 17
2010-07-17 03:48:12.770 RideOnTime[497:307] Sec 18
2010-07-17 03:48:12.775 RideOnTime[497:307] Sec 19
2010-07-17 03:48:12.781 RideOnTime[497:307] Sec 20
2010-07-17 03:48:12.785 RideOnTime[497:307] Sec 21
2010-07-17 03:48:12.790 RideOnTime[497:307] Sec 22
2010-07-17 03:48:12.796 RideOnTime[497:307] Sec 23
○取得方法その2
2010-07-17 03:48:15.293 RideOnTime[497:307] SecNm: 0
2010-07-17 03:48:15.295 RideOnTime[497:307] SecNm: 5
2010-07-17 03:48:15.306 RideOnTime[497:307] SecNm: 6
2010-07-17 03:48:15.309 RideOnTime[497:307] SecNm: 7
2010-07-17 03:48:15.312 RideOnTime[497:307] SecNm: 8
2010-07-17 03:48:15.314 RideOnTime[497:307] SecNm: 9
2010-07-17 03:48:15.316 RideOnTime[497:307] SecNm: 1
2010-07-17 03:48:15.319 RideOnTime[497:307] SecNm: 2
--
ご覧のようにiOS4だと0が始めに来てしまいます。おかげでセクションと時刻データとの組み合わせにもズレが生じて,TableViewが混乱してしまっています。
デベロッパドキュメントにはinitWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:メソッドについて次のように書いてあります。
sectionNameKeyPath
A key path on result objects that returns the section name. Pass nil to indicate that the controller should generate a single section.
The section name is used to pre-compute the section information.
If this key path is not the same as that specified by the first sort descriptor in fetchRequest, they must generate the same relative orderings. For example, the first sort descriptor in fetchRequest might specify the key for a persistent property; sectionNameKeyPath might specify a key for a transient property derived from the persistent property.
う〜む,iOS4ではこの記述通りになっていないような気がするのですが...。