NSManagedObjectクラス

2011. 04. 24
●概要

NSManagedObjectは、Core Dataモデルオブジェクトの要求する全ての基本的な動作を実装する包括的なクラスです。

管理オブジェクトコンテキストに、NSObject(またはNSManagedObjectから継承されていないその他のクラス)のサブクラスの直接のインスタンスを使用することはできません。

NSManagedObjectのカスタムサブクラスを生成することはできますが必ずしも必要ではありません。

カスタムロジックが必要でない場合、NSManagedObjectインスタンスに沿った完全なオブジェクトグラフの形式にすることができます。

管理オブジェクトは、(オブジェクトを表すエンティティの名前、およびその属性と関係の名前を含む)オブジェクトに関するメタデータを提供するエンティティ記述(NSEntityDescriptionのインスタンス)と、オブジェクトグラフへ変更の足跡を残す管理オブジェクトコンテキストを関連付けします。

管理オブジェクトは、Core Dataで使用できるよう適切に構成されていることが重要です。

管理オブジェクトを直接インスタンス化する場合は、指定イニシャライザ(initWithEntity:insertIntoManagedObjectContext:)を呼び出す必要があります。


データストレージ

いくつかの点で、NSManagedObjectは辞書のように動作し、関連付けられたNSEntityDescriptionオブジェクトによって定義されたプロパティのストレージを効率的に提供する、汎用的なコンテナオブジェクトです。

NSManagedObjectは文字列を含む日付、数値といった属性値の一般的な型の範囲をサポートしています。
(詳細についてはNSAttributeDescriptionを参照してください)

したがって、一般的にサブクラスでインスタンス変数を定義する必要はありません。

しかし時には、色やC構造体など、直接サポートしていない型を使用する場合があります。

例えばグラフィックスアプリケーションで、NSColorとNSRect構造体それぞれのインスタンスである色と領域の属性を持ったRectangleエンティティを定義したい場合があります。

いくつかの型は属性を変換して使用できますが、それ以外はNSManagedObjectのサブクラスを生成する必要があります。
(『Non-Standard Persistent Attributes』を参照)


フォールティング

管理オブジェクトは通常、永続ストアが保持するデータを表します。

いくつかの状況では、管理オブジェクトが『フォールト(オブジェクトのプロパティ値が外部データストアからまだ読み込まれていない)』の場合があります。
(詳細は『Faulting and Uniquing』を参照してください)

永続的なプロパティ値にアクセスを試みた場合、フォールトが『発動』し、自動的にストアからデータを取得します。

これは比較的高くつく工程なので(潜在的に永続ストアへのデータの往復が必要になる)、無用なフォールトの発動は回避したいと思うかもしれません。

フォールトを発動させず安全に呼び出すことができるメソッドは、次の通りです。
isEqual:、hash、superclass、class、self、zone、isProxy、isKindOfClass:、isMemberOfClass:、conformsToProtocol:、respondsToSelector:、retain、release、autorelease、retainCount、description、managedObjectContext、entity、objectID、isInserted、isUpdated、isDeleted、faultingState、isFault。

isEqualとhashはフォールトが発動しないので、管理オブジェクトは通常フォールトを発動させずにコレクションに置くことができます。

ただし、コレクションオブジェクトでキー値コーディングメソッドを呼び出すと、管理オブジェクトでvalueForKey:が呼び出されてされて結果を返すため、フォールトが発動します。

descriptionメソッドでフォールトは発動しませんが、オブジェクトの永続プロパティにアクセスするカスタムdescriptionメソッドを実行した場合は、フォールトが発動します。

この場合、descriptionをオーバーライドすることは強く推奨しません。


サブクラス化の注意

管理オブジェクトモデル内のエンティティ記述の組み合わせでは、NSManagedObjectは任意のプロパティと値の検証のサポートを含む、デフォルト動作の豊富なセットを提供します。

しかし、NSManagedObjectのサブクラスにカスタムな機能の実装を望む理由は多いでしょう。

ただし、Core Dataの動作を混乱させないことが重要です。


オーバーライド不可のメソッド

NSManagedObject自体は、管理オブジェクトがCore Dataのインフラストラクチャに適切に統合できるように、NSObjectの多くの機能がカスタマイズされています。

Core DataはNSManagedObjectの以下のメソッドの実装に依存しているので、絶対にオーバーライドしないでください。
primitiveValueForKey:、setPrimitiveValue:forKey:、isEqual:、hash、superclass、class、self、zone、isProxy、isKindOfClass:、isMemberOfClass:、conformsToProtocol:、respondsToSelector:、retain、release、autorelease、retainCount、managedObjectContext、entity、objectID、isInserted、isUpdated、isDeleted、isFault。

上記のメソッドに加えMac OS X v10.5以降でオーバーライドしてはいけないメソッドは以下の通りです。
alloc、allocWithZone:、new、instancesRespondToSelector:、instanceMethodForSelector:、methodForSelector:、methodSignatureForSelector:、instanceMethodSignatureForSelector:、isSubclassOfClass:。


オーバーライド非推奨のメソッド

任意のクラスと同様に、willChangeValueForKey:didChangeValueForKey:withSetMutation:usingObjects:などのキー値を観察するメソッドのオーバーライドは強く推奨しません。

descriptionのオーバーライドは推奨しません。
(このメソッドはデバッグ処理中にフォールトが発動した場合、結果が予測できなくなります)

またinitWithEntity:insertIntoManagedObjectContext:、dealloc、finalizeのオーバーライドも推奨しません。

initWithEntity:insertIntoManagedObjectContext:メソッドで値を変更する際はコンテキストによって通知を行うよう注意を払わないと、変更は保存されません。

ほとんどの初期化のカスタマイズは、いずれかのawake...メソッドで実行する必要があります。

initWithEntity:insertIntoManagedObjectContext:をオーバーライドする場合、メソッド記述の必要条件に準拠しているかを確認する必要があります。
initWithEntity:insertIntoManagedObjectContext:を参照)

通常didTurnIntoFaultは値のクリアにdeallocやfinalizeより多くの時間がかかるので、オーバーライドは推奨しません。
(管理オブジェクトがフォールトになった後は、しばらくの間再利用できない場合があります)

Core Dataは、(アプリケーションの終了時など)全てのシナリオでdeallocまたはfinalizeのどちらかを呼び出すことを保証するものではありません。

したがって、これらのメソッドに含まれている(ユーザのプリファレンスやファイルシステムへの保存や変更などの)副作用を必要とするべきではありません。

要約すると、initWithEntity:insertIntoManagedObjectContext:、dealloc、finalizeのためには、Core Dataは管理オブジェクトのライフサイクルが終わるまで(つまり、生のメモリ管理を)排他的に制御を確保することを念頭に置くことが重要です。

これはフレームワークが、一意化や結果による関係の維持だけでなく、他の候補よりも遥かにより良い性能を提供できるようにするためです。


メソッドをオーバーライドする際の考慮

以下のメソッドは、きめ細かくて大規模な処理を行わないことを意図しています。

これらのメソッドでフェッチや保存をしてはいけません。

特に、管理オブジェクトコンテキスト上で副作用を利用するべきではありません。

・initWithEntity:insertIntoManagedObjectContext:
・didTurnIntoFault
・willTurnIntoFault
・dealloc
finalize

更にメソッドはオーバーライドすべきではなく、オーバーライドする場合は最初にスーパークラスを呼び出す必要があり、それにはawakeFromInsert、awakeFromFetch、および準拠するメソッドを含みます。

awakeFromFetchの関係は変更しないよう注意してください。
(詳細はメソッドの説明を参照してください)


カスタムアクセサメソッド

通常、管理オブジェクトに対応する管理オブジェクトモデルの、エンティティで定義されているプロパティのカスタムアクセサメソッドを記述する必要はありません。

それを望む、あるいは必要がある場合、従わなければならないいくつかの実装パターンがあります。

これらは『Core Dataプログラミングガイド』の『管理オブジェクトのアクセサメソッド』で説明されています。

Mac OS X v10.5では、Core Dataは自動的にアクセサメソッド(とプリミティブアクセサメソッド)を生成します。

属性と一対一の関係では、Core Dataは標準のゲットとセットのアクセサメソッドを生成し、一対多の関係では、Core Dataは『キー値コーディングプログラミングガイド』の『キー値コーディングのアクセサメソッド』で説明されているようにインデックス付きのアクセサメソッドを生成します。

ただしコンパイラの警告を抑制するため、アクセサメソッドを宣言するか、またはObjective-Cプロパティを使用する必要があります。

完全な説明については、『Core Dataプログラミングガイド』の『管理オブジェクトのアクセサメソッド』を参照してください。

Mac OS X v10.4では、valueForKey:などの標準のキー値コーディングメソッドを使用して、プロパティにアクセスすることができます。

ただし、コンパイル時の型チェックやスペルを間違えたキー名を回避するためには、カスタムアクセサを実装すると便利です。


カスタムインスタンス変数

デフォルトでは、NSManagedObjectはオブジェクトとして内部構造にプロパティを格納しており、一般的にCore Dataは、カスタムインスタンス変数を使用するよりも独自の制御下にあるストレージで作業する方がより効率的です。

NSManagedObjectは、文字列を含む日付、数値といった属性値のための、一般的な型の範囲のサポートを提供します。
(詳細はNSAttributeDescriptionを参照してください)

色やC構造体など直接サポートしていない型を使用する場合は、『Non-Standard Persistent Attributes』で説明されているように、変換可能な属性またはNSManagedObjectのサブクラスの生成のどちらかを使用することができます。

例えば描画アプリケーションなどで、頻繁に計算で使用する大きさを表す変数としてxとy座標をスカラー値として変数を表すと便利です。

スカラー値として属性値を表すには、他のクラスと同様にインスタンス変数を宣言します。

また『Managed Object Accessor Methods』で説明されている適切なアクセサメソッドを実装する必要があります。

カスタムインスタンス変数を定義した場合、派生した属性値や他の一時的なプロパティを格納するために、これらの変数をdidTurnIntoFaultではなくdeallocでクリーンアップする必要があります。


検証メソッド

NSManagedObjectは検証プロパティと相互プロパティ値のための一貫性のあるフックを提供します。

通常はvalidateValue:forKey:error:をオーバーライドせず、代わりにNSKeyValueCodingプロトコルで定義されている、validate<key>:error:形式のメソッドを実装します。

相互プロパティ値を検証する場合は、validateForUpdate:または関連する検証メソッドをオーバーライドすることができます。

カスタムプロパティの検証メソッド内でvalidateValue:forKey:error:を呼び出さないでください。

実行時にvalidateValue:forKey:error:を呼び出すと無限ループが生成されます。

カスタム検証メソッドを実装する場合、通常は直接呼び出してはいけません。

代わりに、適切なキーを使用してvalidateValue:forKey:error:を呼び出す必要があります。

これは管理オブジェクトモデルで定義された全ての制約に適用されることが保証されます。

(validateForUpdate:などの)カスタム相互プロパティの検証メソッドを実装する場合、最初にスーパークラスの実装を呼び出す必要があります。

これは個々のプロパティについて検証メソッドが呼び出されることを保証します。

1回の処理に複数の検証失敗がある場合、配列でそれらを収集し、NSErrorオブジェクト内のuserInfo辞書に(キーNSDetailedErrorsKeyを使用して)配列を追加して戻る必要があります。

例は『Model Object Validation』を参照してください。



●タスク

管理オブジェクトの初期化

– initWithEntity:insertIntoManagedObjectContext:

管理オブジェクトのIDの取得

– entity
– objectID
– self

状態情報の取得

– managedObjectContext
– isInserted
– isUpdated
– isDeleted
– isFault
– faultingState
– hasFaultForRelationshipNamed:

ライフサイクルと変更イベントの管理

+ contextShouldIgnoreUnmodeledPropertyChanges
– awakeFromFetch
– awakeFromInsert
– awakeFromSnapshotEvents:
– changedValues
– committedValuesForKeys:
– prepareForDeletion
– dealloc
– willSave
– didSave
– willTurnIntoFault
– didTurnIntoFault

サポートしているキー値コーディング

– valueForKey:
– setValue:forKey:
– mutableSetValueForKey:
– primitiveValueForKey:
– setPrimitiveValue:forKey:

検証

– validateValue:forKey:error:
– validateForDelete:
– validateForInsert:
– validateForUpdate:

サポートしているキー値監視

+ automaticallyNotifiesObserversForKey:
– didAccessValueForKey:
– observationInfo
– setObservationInfo:
– willAccessValueForKey:
– didChangeValueForKey:
– didChangeValueForKey:withSetMutation:usingObjects:
– willChangeValueForKey:
– willChangeValueForKey:withSetMutation:usingObjects:



●クラスメソッド



●インスタンスメソッド

・managedObjectContext

- (NSManagedObjectContext *)managedObjectContext

レシーバが登録されている管理オブジェクトコンテキストを返します。

このメソッドは、レシーバがコンテキストから削除されている場合はnilを返します。

レシーバがフォールトの場合、このメソッドを呼び出しても発動しません。


setValue:forKey:

- (void)setValue:(id)value forKey:(NSString *)key

指定された値に、レシーバの指定されたプロパティを設定します。

keyがモデルによって定義されたプロパティではない場合、メソッドは例外を発生させます。

keyが対一の関係で識別される場合、レシーバへの値によって指定されたオブジェクトと関連付けされ、以前に関連付けられていたオブジェクトは解除されます。

指定したコレクションオブジェクトとキーが対多の関係で識別される場合、レシーバにコレクションに格納されているオブジェクトが関連付けられ、以前に関連付けられていたオブジェクトは解除されます。

このメソッドは、レシーバのクラスが明示的にkeyに対するキー値コーディングに準拠したアクセサメソッドを提供しない限り、管理オブジェクトの汎用的な辞書ストレージへのアクセスするNSManagedObjectによってオーバーライドされます。

重要:このメソッドはオーバーライドしないでください。

value:keyで指定されたプロパティの新しい値を指定します。

key:レシーバのプロパティのいずれかの名前を指定します。


valueForKey:

- (id)valueForKey:(NSString *)key

keyで指定されたプロパティの値を返します。

keyがモデルによって定義されたプロパティではない場合、メソッドは例外を発生させます。

このメソッドは、レシーバのクラスが明示的にkeyに対するキー値コーディングに準拠したアクセサメソッドを提供しない限り、管理オブジェクトの汎用的な辞書ストレージへのアクセスするNSManagedObjectによってオーバーライドされます。

重要:このメソッドはオーバーライドしないでください。

key:レシーバのプロパティのいずれかの名前を指定します。



●定数



参考文献

NSManagedObject Class Reference






Lifestyle 650 home entertainment system
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
10 | 2017/11 | 12
Sun Mon Tue Wed Thu Fri Sat
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 - -
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

Lifestyle 650 home entertainment system
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR