0

実行したい非常に単純なフェッチ要求があります。私のエンティティの 1 つには、smartCollectionIds という属性があり、そのタイプは変換可能です。NSArrayこの属性を使用して、単純な文字列を格納します。私のコードでは、 を使用しNSfetchedResultsControllerてテーブルビューを作成しています。使用する述語は次のとおりです。

predicate=[NSPredicate predicateWithFormat:@"smartCollectionIds!=nil && (%@ IN smartCollectionIds)",@"87F173A5-863D-4ECE-9673-A61D8F1E01FC-6285-000009A9CBAF3290"];

ただし、これにより、特にフェッチを実行するときにパイントでクラッシュが発生します。ただし、最初にフェッチを使用してすべてのオブジェクトを配列にロードし、次に上記の述語でそれらを除外すると、アプリはクラッシュせず、期待どおりの結果が得られます。したがって、基本的に このコードは機能しません

-(void) tryTO
{
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Tweetary" inManagedObjectContext: [[ChubbyEyetwitterEngine sharedInstance] getManagedObjectContextForUse]];

NSPredicate *predicate;

predicate=[NSPredicate predicateWithFormat:@"smartCollectionIds!=nil && (%@ IN smartCollectionIds)",@"87F173A5-863D-4ECE-9673-A61D8F1E01FC-6285-000009A9CBAF3290"];

NSSortDescriptor *secondarySortKey = [[[NSSortDescriptor alloc] initWithKey:@"created_at" ascending:FALSE] autorelease];

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease] ;
[request setEntity:entity];
[request setPredicate:predicate];
[request setSortDescriptors:[NSArray arrayWithObjects:
                             secondarySortKey
                             ,nil]];
[request setFetchLimit:30];  //30


NSError *error;

NSArray *results = [[[ChubbyEyetwitterEngine sharedInstance] getManagedObjectContextForUse] executeFetchRequest:request error:&error];

if (error != nil)
{
     NSLog(@"Results are %d",[results count]);

}else{
    NSLog(@"findAllObjectsInContext error %@",error);

}

}

しかし、これは機能します

  NSArray *tweets = [Tweetary findAllObjectsInContext:[[ChubbyEyetwitterEngine sharedInstance] getManagedObjectContextForUse]];

NSLog(@"Before filter count is %d",[tweets count]);

predicate=[NSPredicate predicateWithFormat:@"smartCollectionIds!=nil && (%@ IN smartCollectionIds)",@"87F173A5-863D-4ECE-9673-A61D8F1E01FC-6285-000009A9CBAF3290"];

predicate=[NSPredicate predicateWithFormat:@"smartCollectionIds!=nil && (%@ IN smartCollectionIds)",@"87F173A5-863D-4ECE-9673-A61D8F1E01FC-6285-000009A9CBAF3290"];

NSArray *bNames = [tweets filteredArrayUsingPredicate:predicate];

NSLog(@"FINAL Results %d",[bNames count]);



+ (NSArray *)findAllObjectsInContext:(NSManagedObjectContext *)context;
  {


 @synchronized(self){

NSEntityDescription *entity = [self entityDescriptionInContext:context];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entity];
NSError *error = nil;
NSArray *results = [context executeFetchRequest:request error:&error];
if (error != nil)
{
    //handle errors
    //NSLog(@"findAllObjectsInContext error %@",error);
}
return results;
  }
 }

簡単に言えば、最初にオブジェクトを配列にロードしてからフィルター述語を適用するのではなく、NSfetchedResultsController を使用するときにフェッチ述語が機能する必要があります。誰かが私を正しい方向に向けることができますか/フィルター処理されていないデータセットを配列にロードした後にのみ述語が機能する理由を理解できますか?

4

1 に答える 1

5

述語を含むコア データ フェッチ リクエストは、SQLite クエリに変換され、SQLite レベルで実行されます。変換可能な配列は、SQLite データベースに blob として格納されるため、フェッチ リクエストで配列として扱うことはできません。

最初に要素をフェッチすると、プロパティにアクセスしたときに blob が配列に変換されます。したがって、フェッチされたオブジェクトの配列のフィルタリングは期待どおりに機能します。

回避策はないと思います。フェッチ リクエストで変換可能なプロパティをフィルタリングすることはできません。

于 2013-08-16T12:12:20.977 に答える