我对NSFetchedResultsCOntroller有一个很大的问题。我正在使用fetchedResultsContrioller,我有3个标签的界面。他们也使用核心数据。但我只有一个问题。
Faktura *faktura = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = faktura.NumerFV; // THE CRASH IS HERE
int productsCount = [faktura.Produkty count]; // OR HERE
NSString *kontrahentName = [faktura.Kontrahent valueForKey:@"NazwaKrotka"]; // OR HERE
cell.detailTextLabel.text = [NSString stringWithFormat:@"nabywca: %@, produktów: %d",kontrahentName, productsCount];
cell.imageView.image = [UIImage imageNamed:@"faktura_cell_image.png"];
cell.hidesImageWhileEditing = YES;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Faktura
是我的NSManagedObject子类。
-[CFDictionary retain]: message sent to deallocated instance 0x5d619d0
我的fetchedResultsController实现:
- (NSFetchedResultsController *)fetchedResultsController {
if (__fetchedResultsController != nil) return __fetchedResultsController;
// Setup the table
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Faktura" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Setup the sort descriptors
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"DataWystawienia" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// Create the fetched results controller
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) { // THE CRASH IS HERE UNLESS I INIT NSFetchedResultsController WITH cacheName:nil. (IF IT'LL BE cacheName:@"Root" IT CRASHES.)
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Błąd Krytyczny" message:@"Wystąpił nieznany błąd przy zmienianiu zawartości w bazie danych. Dla dobra twoich danych prosimy niezwłocznie wyjść z aplikacji i spróbować ponownie." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alert show];
[alert release];
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return __fetchedResultsController;
}
Faktura.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface NSArrayToDataTransformer : NSValueTransformer @end
@interface NSDictionaryToDataTransformer : NSValueTransformer @end
@interface Faktura : NSManagedObject
@property (nonatomic, retain) NSDate * DataZaplaty;
@property (nonatomic, retain) NSString * NumerFV;
@property (nonatomic, retain) NSDate * DataWystawienia;
@property (nonatomic, retain) NSDate * DataSprzedazy;
@property (nonatomic, retain) id Produkty;
@property (nonatomic, retain) id Kontrahent;
@end
Faktura.m
#import "Faktura.h"
@implementation Faktura
@dynamic DataZaplaty;
@dynamic NumerFV;
@dynamic DataWystawienia;
@dynamic DataSprzedazy;
@dynamic Produkty;
@dynamic Kontrahent;
+ (void)initialize {
if (self == [Faktura class] ) {
NSArrayToDataTransformer *arrayTransformer = [[NSArrayToDataTransformer alloc] init];
[NSValueTransformer setValueTransformer:arrayTransformer forName:@"NSArrayToDataTransformer"];
NSDictionaryToDataTransformer *dictTransformer = [[NSDictionaryToDataTransformer alloc] init];
[NSValueTransformer setValueTransformer:dictTransformer forName:@"NSDictionaryToDataTransformer"];
}
}
@end
@implementation NSArrayToDataTransformer
+ (BOOL)allowsReverseTransformation {
return YES;
}
+ (Class)transformedValueClass {
return [NSData class];
}
- (id)transformedValue:(id)value {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
return data;
}
- (id)reverseTransformedValue:(id)value {
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [array autorelease];
}
@end
@implementation NSDictionaryToDataTransformer
+ (BOOL)allowsReverseTransformation {
return YES;
}
+ (Class)transformedValueClass {
return [NSData class];
}
- (id)transformedValue:(id)value {
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:value];
return data;
}
- (id)reverseTransformedValue:(id)value {
NSDictionary *dict = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [dict autorelease];
}
@end
我的Faktura
对象插入代码
- (void)fakturaCreator:(FakturaCreator *)form didEndWithValues:(NSDictionary *)values {
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
Faktura *newFaktura = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[newFaktura setNumerFV:[values valueForKey:@"id"]];
[newFaktura setDataWystawienia:[values valueForKey:@"creationDate"]];
[newFaktura setDataSprzedazy:[values valueForKey:@"sellDate"]];
[newFaktura setDataZaplaty:[values valueForKey:@"paymentDate"]];
[newFaktura setKontrahent:[values valueForKey:@"kontrahent"]];
[newFaktura setProdukty:[values valueForKey:@"produkty"]];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.emptySectionView setHidden:YES];
}
FakturaCreator
是我的UIViewController,用户在其中创建发票。值数组包含值字典:我的发票号(NSString
),各种日期(NSDate
),客户端(NSDictionary
)和产品(NSArray
)。
请帮帮我! 如果你想要一些额外的代码,我会把它放在这里。
编辑: definetly objectAtIndexPath:
错误。当我评论所有单元格设置代码(它将显示空单元格)然后尝试删除单元格时,应用程序在包含objectatIndexPath:
的行崩溃。
编辑#2:有人吗?请帮助我...... :(
答案 0 :(得分:2)
我想我看到了问题。在NSArrayToDataTransformer
中,您有:
- (id)reverseTransformedValue:(id)value {
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [array autorelease];
}
由于unarchiveObjectWithData:
不以“alloc”,“new”,“copy”或“mutableCopy”开头,因此您不拥有该对象,因此可能无法自动释放它。您的NSDictionaryToDataTransformer
中存在同样的问题。
答案 1 :(得分:1)
您将值变换器包含在类中并且使用+initialize
是非标准的。尽管+initialize
应该有效,但建议在Core Data文档中不要使用任何类型的初始化方法,而是依赖awakeFromFetch
进行初始化。
我会检查你的tableview方法,例如numberOfRowsInSection:
,以确保从tableview中获取正确的索引。如果tableview中的行和fetchedObjects
数组的计数不同步,则可能会发生此类崩溃。