【发布时间】:2012-06-06 11:20:36
【问题描述】:
我想获取大约 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 to-many relationships
从我的角度来看,我看到了 2 种方法: 1)执行FetchRequest,但提供:对象不会出现在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];
【问题讨论】:
-
仅供参考,您不应该在单个实体/行中存储 5MB 的数据。 Apple 指南明确讨论了这一点。除非图像非常小,否则应将图像存储在文件系统中,并且仅将其路径存储在实体中。
-
您能否明确证明指向 Apple 指南的链接。所以我可以阅读它。 (我听说过,但我想自己读)
标签: iphone sorting core-data nsmanagedobject nsfetchrequest