iOS/iPhone/iPad/watchOS/tvOS/MacOSX/Android プログラミング, Objective-C, Cocoa, Swiftなど
CoreDataのエンティティは、そのままの状態だと管理オブジェクトクラスで操作する事になる。
/* 値の取得 */
[管理オブジェクト valueForKey:@"キー名"]
/* 値の設定 */
[管理オブジェクト setValue:値 forKey:@"キー名"];
規模が大きくなり、これだと煩雑だったり、単純な属性の参照/設定以上の事を行いたい場合、カスタム管理オブジェクトクラスの作成を考えると思う。
サンプル・コードのエンティティ属性を読み書きしている箇所を以下のように変更する。
[newManagedObject setValue:[NSDate date] forKey:@"timeStamp"];
↓
newManagedObject.timeStamp = [NSDate date];
cell.textLabel.text = [[object valueForKey:@"timeStamp"] description];
↓
cell.textLabel.text = [object.timeStamp description];
このカスタム管理オブジェクトクラスは、管理オブジェクトモデルのエンティティから生成という手段のみで作成される。つまり、新規作成のみで作成済みの場合は上書き生成となる。
もし、カスタム管理オブジェクトクラスに自分独自のカスタマイズを施している場合、上書き生成は困るのでどうすればいいのか?岸川さんの日記『CoreData の NSManagedObject のサブクラスを変更する場合はカテゴリを使うと便利』が参考になった。
例えば、カスタム管理オブジェクトクラスのファイル名が、Event.[hm] の場合、独自のカスタマイズ・コードをこのファイルに記述するのではなくて、例えば、Event_description.[hm] という名前のカテゴリを追加で作成する。
#import "Event.h"
@interface Event(description)
- (NSString *)description; /* override */
@end
@implementation Event(description)
- (NSString *)description
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy/MM/dd HH:mm:ss"];
NSString *str = [formatter stringFromDate:self.timeStamp];
return str;
}
@end
サンプルでは、EventクラスのtimeStampプロパティのdescriptionをセルに設定していたが、カテゴリでオーバーライドしたEventクラスのdescriptionを設定するように変更する。
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
Event *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [object description];
}
実行。拡張した形式で表示されている。