約 200 個の NSManagedObject を取得したいのですが、それぞれのサイズは約 5Mb です。executeFetchRequest を使用すると、メモリ警告が表示され、アプリがクラッシュします (フェッチされた NSManagedObjects が iPhone の RAM に表示されるため)。executeFetchRequest を使用できる場合は、sortdescriptor を使用して ID でデータを並べ替えることができます。しかし、できません (または、適切なプロパティを NSFetchRequest に設定する必要があるかもしれませんが、どのプロパティかわかりません)。そのため、大量のデータをロードするために別のアプローチを使用しました。多くのエンティティ SpecificImage を持つエンティティ アルバムがあります。そして、このコードを使用して、現在のアルバムのすべての画像を取得します。
- (NSMutableSet *)getAllSpecificImages
{
NSString *entityName = kEntityName;
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSEntityDescription *entityDesctiption = [NSEntityDescription
entityForName: entityName
inManagedObjectContext:context];
// check if town exists
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id == %d", self.CurrentCategoryItemID];
NSFetchRequest *requestToCheckExistense = [[NSFetchRequest alloc] init];
[requestToCheckExistense setEntity:entityDesctiption];
[requestToCheckExistense setPredicate:predicate];
NSArray *objects = [context executeFetchRequest:requestToCheckExistense error:nil];
[requestToCheckExistense release];
if (objects == nil)
{
NSLog(@"there was an error");
return nil;
}
NSManagedObject *object;
if ([objects count] > 0)
{
// edit item
object = [objects objectAtIndex:0];
}
else
{
// if object doesn't exist, find max id to imlement autoincrement
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesctiption];
NSArray *allobjects = [context executeFetchRequest:request error:nil];
[request release];
NSInteger newID = 1;
if ([allobjects count] > 0)
{
NSNumber *maxID = [allobjects valueForKeyPath:@"@max.id"];
newID = [maxID intValue] + 1;
}
// write item
object = [NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context];
[object setValue:[NSNumber numberWithInt:newID] forKey:@"id"];
self.CurrentCategoryItemID = newID;
}
NSMutableSet *set = [object mutableSetValueForKey:@"specificImages"];
return set;
}
次に、NSManagedObjects の配列を取得します
NSMutableArray *array = [NSMutableArray arrayWithArray:[setOfManagedObjectsSpecificImages allObjects]];
しかし、この NSManagedObjects の並べ替えられた配列を取得しようとすると、再びメモリ警告が表示され、アプリがクラッシュします。使ってみた
NSSortDescriptor *sortDiscriptor = [NSSortDescriptor sortDescriptorWithKey:@"id" ascending:YES];
[array sortUsingDescriptors:[NSArray arrayWithObject:sortDiscriptor]];
と
[self quickSort:array left:0 right:([array count] - 1)];
どこ
- (void)quickSort: (NSMutableArray *)arr left:(NSInteger)left right:(NSInteger) right
{
@autoreleasepool {
int i = left, j = right;
int pivot = [((SpecificImage *)[arr objectAtIndex:(left + right) / 2]).id intValue];
/* partition */
while (i <= j) {
while ([((SpecificImage *)[arr objectAtIndex:i]).id intValue] < pivot)
{
i++;
}
while ([((SpecificImage *)[arr objectAtIndex:j]).id intValue] > pivot)
{
j--;
}
if (i <= j) {
[arr exchangeObjectAtIndex:i withObjectAtIndex:j];
i++;
j--;
}
};
/* recursion */
if (left < j)
{
[self quickSort:arr left:left right:j];
}
if (i < right)
{
[self quickSort:arr left:i right:right];
}
}
}
しかし、それは役に立ちませんでした。
私の見解では、一連の NSManagedObjects を取得すると、それらは RAM にありません。ただし、並べ替え中に RAM に表示されます。
ソートされた NSMutableSet を取得したかった (設定しようとした:
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"specificImages.id" ascending:YES];
しかし、私は得ました
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here'
この問題はNSSortDescriptor対多関係のもう1つの質問であると説明しました
私の観点から、私は2つのアプローチを見ています:1)executeFetchRequest、しかし提供:オブジェクトはRAMに表示されません(方法はわかりませんが、それが可能であることはほとんど確信しています)2)クイックを変更します提供する並べ替え: オブジェクトは RAM に表示されません
更新 ここに私のコードがあります。ここでは、executeFetchRequest を使用してオブジェクトをフェッチしようとしています (オブジェクトは RAM にあり、(RAM ではなく) 障害オブジェクトにしたい):
+ (NSMutableSet *)GetImagesWithPredicate:(NSPredicate *)predicate
{
NSString *entityName = kEntityName;
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];;
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSEntityDescription *entityDesctiption = [NSEntityDescription
entityForName: entityName
inManagedObjectContext:context];
// find object
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesctiption];
[request setPredicate:predicate];
NSArray *objects = [context executeFetchRequest:request error:nil];
[request release];
if (objects == nil)
{
NSLog(@"there was an error");
return nil;
}
NSMutableSet *set = [NSMutableSet setWithArray:objects];
return set;
}
ここで述語:
NSMutableArray *allID = [NSMutableArray array];
for (int i = 1; i < 639; i++)
{
[allID addObject:[NSNumber numberWithInt:i]];
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id in %@", allID];