2

私がこれを行うと言う:

NSManagedObjectContext *context = #a managed object context";
NSString *entityName = #an entity name#;
NSFetchRequest *requestForAll = [NSFetchRequest requestWithEntityName:entityName];
NSArray *allObj = [context executeFetchRequest:requestForAll];

for (NSString *name in allNamesArray){
    NSFetchRequest *requestForOne = [NSFetchRequest requestWithEntityName:entityName];
    requestForOne.predicate = [NSPredicate predicateWithFormat:@"name == %@",name];
    NSArray *ObjsWithName = [context executeFetchRequest:requestForOne];
    #do some work with the obj#
}

ループ内のフェッチでは、毎回永続ストアへのトリップが発生しますか?または、これらのフェッチはcoredataの行キャッシュでのみ実行されますか?

編集 私はテストコードの断片を書きました:「Person」という名前のコアデータエンティティを作成する必要があり、文字列型の「name」という名前の属性が必要です。

このコードを使用して、いくつかのデータを入力します。

self.array = @[@"alkjsdfkllaksjdf",@"asldjflkajdklsfjlk;aj",@"aflakjsdl;kfjalksdjfklajkldhkl;aj",@"aljdfkljalksdjfl;j" ,@"flajdl;kfjaklsdjflk;j",@"akldsjfklajdslkf",@"alkdjfkljaklsdjflkaj",@"alsdjflkajsdflj",@"adlkfjlkajsdfkljkla",@"alkdjfklajslkdfj"];

NSString *firstRunKey = @"oh its first run!";
NSString *firstRun = [[NSUserDefaults standardUserDefaults] objectForKey:firstRunKey];
if (!firstRun) {
    for (NSString *name in self.array) {
        Person *p = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];
        p.name = name;
    }
}
[self.managedObjectContext save];
[[NSUserDefaults standardUserDefaults] setObject:firstRunKey forKey:firstRunKey];
[[NSUserDefaults standardUserDefaults] synchronize];

この2つのメソッドのプロファイルを作成すると、UsingCoreDataの方がFilterArrayを使用するよりもはるかに時間がかかることがわかります。

static int caseCount = 1000;
-(void)usingCoreData
{
    NSLog(@"core data");
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
    NSArray *allPersons = [self.managedObjectContext executeFetchRequest:request error:nil];

    for (int i = 0; i < caseCount; i++){
        for (NSString *name in self.array) {
            request.predicate = [NSPredicate predicateWithFormat:@"name == %@",name];
            NSArray *result = [self.managedObjectContext executeFetchRequest:request error:nil];
        }
    }
}

-(void)usingFilterArray
{
    NSLog(@"filter array");
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Person"];
    NSArray *allPersons = [self.managedObjectContext executeFetchRequest:request error:nil];

    for (int i = 0; i < caseCount; i++){
        for (NSString *name in self.array) {
            NSArray *array = [allPersons filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"name == %@",name]];
        }
    }
}
4

2 に答える 2

2

自分の質問に自分で答える必要があると思います。

テストしたところ、フェッチが実行されるたびに、コア データが NSFetchRequest を SQL コマンドに変換し、データベース クエリを呼び出します。クエリの結果は最初に NSManagedObjectIDs であり、NSManagedObjectID から NSManagedObject を取得するためにキャッシュが適用されます。

結論として、オブジェクトはキャッシュされますが、クエリ結果はキャッシュされません。

つまり、同じ NSFetchRequest を 10 回実行すると、永続ストアが 10 回クエリされますが、同じ結果が 10 回得られます。したがって、このような状況では、メモリ内の配列をフィルタリングする方がフェッチするよりもパフォーマンスが高くなります。

于 2012-12-26T07:18:15.550 に答える
0

取得は、利用可能な場合、指定されたキャッシュから行われます。

NSFetchedResultsController編集:キャッシュを使用するを設定する方法を示す優れたチュートリアルへのリンクを次に示します。

http://www.raywenderlich.com/?p=999

于 2012-12-12T05:45:47.880 に答える