4

NSFetchRequest の propertiesToFetch は必要なプロパティを制限できることがわかっているため、メモリのフットプリントを削減できます。このようにすると:

request.propertiesToFetch = [NSArray arrayWithObjects:@"nID", nil];

と:

    NSString *strID = [NSString stringWithFormat:@"%@", aPerson.nID];
cell.textLabel.text = strID;

次に、出力をデバッグします(障害を発生させません):

CoreData: sql: SELECT t0.Z_ENT, t0.Z_PK, t0.ZNID FROM ZPERSON t0 ORDER BY t0.ZNID

しかし、モデル化されていない新しいプロパティを NSManagedObject Person のサブクラスに追加すると、奇妙なことが起こりました。ちょうどこのような:

@interface Person (Ex)
@property (nonatomic, retain) NSString *strTempName;
@end

@implementation Person (Ex)
@dynamic strTempName;

-(void)setStrTempName:(NSString *)strTempName
{
    [self setPrimitiveValue:strTempName forKey:@"strTempName"];
}

-(NSString*)strTempName
{
    return [self primitiveValueForKey:@"strTempName"];
}

そして、これは新しいモデル化されていないプロパティにアクセスする場所です:

NSString *strTT = aPerson.strTempName;

次に出力をデバッグします。

2013-05-06 10:43:07.789 TestCoreData[988:c07] CoreData: sql: SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBISFORTEST, t0.ZBISINTRASH, t0.ZNID, t0.ZSTRNAME, t0.ZSTROK, t0.ZSTROK2, t0.ZSTRTEST1, t0.ZSTRTEST2, t0.ZADEPART, t0.ZAMIDDLETHUMNAIL, t0.ZANORMALPIC, t0.ZASMALLTHUMNAIL FROM ZPERSON t0 WHERE  t0.Z_PK = ? 
2013-05-06 10:43:07.790 TestCoreData[988:c07] CoreData: annotation: sql connection fetch time: 0.0010s
2013-05-06 10:43:07.791 TestCoreData[988:c07] CoreData: annotation: total fetch execution time: 0.0018s for 1 rows.
2013-05-06 10:43:07.792 TestCoreData[988:c07] CoreData: annotation: fault fulfilled from database for : 0x898a030 <x-coredata://CAD35D43-F6B2-4463-B59B-C9A3CD488935/Person/p51846>

上記の出力メッセージから、SELECT t0.Z_ENT、t0.Z_PK、t0.ZNID の代わりに、SELECT すべてのプロパティ文が生成され、障害が発生する原因となったモデル化されていないプロパティを見つけることができます。

ただし、モデル化されていないプロパティに関するいくつかのメッセージを読みました(ここにリンクがあります):

モデル化されていないプロパティはカスタム NSManagedObject サブクラスの属性にすぎず、エンティティではないため、障害オブジェクトはそれらについて何も知りません。Fault オブジェクトはデータ モデルから初期化されるため、それらが応答するすべてのキーはデータ モデルに含まれている必要があります。これは、モデル化されていないプロパティの要求に対して障害が確実に応答しないことを意味します。

なぜ奇妙なことが起こったのですか?

前もって感謝します。


@匿名、

選択肢 1): アプリがクラッシュし、デバッグ出力に次のように表示されました。

2013-05-06 14:03:05.665 TestCoreData[1794:c07] -[Person strTempName]: unrecognized selector sent to instance 0x6ba77b0
2013-05-06 14:03:30.395 TestCoreData[1794:c07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Person strTempName]: unrecognized selector sent to instance 0x6ba77b0'

選択 2): 最初に、willAccessValueForKey などのメソッドは、NSManagedObject.h のコメントと同様に、KVO 変更通知を送信します。

- (void)willAccessValueForKey:(NSString *)key;      // read notification
- (void)didAccessValueForKey:(NSString *)key;       // read notification (together with willAccessValueForKey used to maintain inverse relationships, to fire faults, etc.) 

第二に、選択肢 2) のコードに続いて、(障害を発生させる) 奇妙なことはまだ私のアプリで生きています。

また、あなたの返信に感謝します。

4

3 に答える 3

0

うまくいかないことがあります:

最初: @dynamic が間違っているのは正しいです。アクセサーはコードにあります。動的なものは何もありません。

2 番目: プリミティブ アクセサーは、モデル化されたプロパティ用です。あなたは「ivarプロパティ」を持っています。他の場所で使用するのと同じように使用してください。(ただし、…access… および …change… メソッドを追加します。)

それを変更した後、障害が発生するかどうかを再確認してください。

+++ -didAccessValueForKey: (NSManagedObject) のドキュメントに、正しい実装のサンプルがあります:

- (NSString *)firstName
{
    [self willAccessValueForKey:@"firstName"];
    NSString *rtn = firstName;
    [self didAccessValueForKey:@"firstName"];
    return rtn;
}
于 2013-05-06T21:24:45.210 に答える