![](/img/trans.png)
[英]Core Data: Adding objects from NSMutableArray to NSMutableSet?
[英]Core Data. Sort NSMutableSet of big size NSManagedObject
我想獲取大約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)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];
tl;代碼。
CoreData有一個東西。 它被稱為斷層 。 故障對象意味着您有對該對象的引用,該數據仍在存儲中(您的“不在RAM中”版本)。 要刪除一個對象,你必須調用valueForKey:
方法並獲取任何屬性(這會加載除關系之外的整個對象)。 在進行排序時,核心數據在內部調用valueForKey:
這會導致您的圖像數據被加載。
我的建議是:創建一個名為ImageDescriptor
的獨立實體,您可以在其中保存排序所需的所有屬性。 該實體將與實際二進制圖像數據保持一對一的關系,您只能在需要時獲取(即使用延遲提取)。
我使用了Eimantas方法,但我得到了如何獲取在RAM中記錄它們的對象。 我使用了includesPropertyValues
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.