NSFetchedResultsController objectAtIndexPath崩溃(EXC_BAD_ACCESS) [英] NSFetchedResultsController objectAtIndexPath crash (EXC_BAD_ACCESS)
问题描述
我对NSFetchedResultsCOntroller有很大的疑问。我正在使用fetchedResultsContrioller,并且具有3个标签的界面。他们也使用核心数据。但是我只有一个问题。
Faktura * faktura = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = faktura.NumerFV; //此处产生了崩溃
int productsCount = [faktura.Produkty count]; //或此处
NSString * kontrahentName = [faktura.Kontrahent valueForKey:@ NazwaKrotka]; // //或在这里
cell.detailTextLabel.text = [NSString stringWithFormat:@ nabywca:%@,产品:%d,kontrahentName,productsCount];
cell.imageView.image = [UIImage imageNamed:@ faktura_cell_image.png];
cell.hidesImageWhileEditing = YES;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
Faktura
是我的NSManagedObject子类。
NSZombie说:
-[CFDictionary keep]:发送到已释放实例0x5d619d0
我的fetchedResultsController实现:
-(NSFetchedResultsController *)fetchedResultsController {
if(__fetchedResultsController!= nil)返回__fetchedResultsController;
//设置表
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@ Faktura inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
//设置排序描述符
NSSortDescriptor * sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:@ DataWystawienia ascending:YES];
NSArray * sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,nil];
[fetchRequest setSortDescriptors:sortDescriptors];
//创建访存结果控制器
NSFetchedResultsController * aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequestmanagedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
aFetchedResultsController.delegate =自我;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController版本];
[fetchRequest版本];
[sortDescriptor版本];
[sortDescriptors版本];
NSError *错误=无;
if(![self.fetchedResultsController performFetch:& error]){//除非我使用NFSetchedResultsController用cacheName:nil初始化,否则会产生崩溃。 (如果它是cacheName:@ Root IT崩溃。)
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@BłądKrytyczny消息:@Wystąpiłnieznanybłądprzy zmienianiuzawartościci w bazie danych。Dla dobra twoich danych表示歉意niezwłoczniewyjśćz aplikacji ispróbowaćponownie。委托:自我cancelButtonTitle:@确定 otherButtonTitles:无];
[警报显示];
[警报发布];
NSLog(@未解决的错误%@,%@,错误,[错误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(非原子,保留)NSDate * DataZaplaty;
@property(非原子,保留)NSString * NumerFV;
@property(非原子,保留)NSDate * DataWystawienia;
@property(非原子,保留)NSDate * DataSprzedazy;
@property(非原子的,保留的)id产品
@property(非原子的,保留的)id Kontrahent;
@end
Faktura.m
#import Faktura.h
@implementation Faktura
@动态DataZaplaty;
@动态NumerFV;
@dynamic DataWystawienia;
@dynamic DataSprzedazy;
@动态产品;
@dynamic Kontrahent;
+(void)初始化{
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 {
返回是;
}
+(Class)transformedValueClass {
return [NSData class];
}
-(id)transformedValue:(id)value {
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:value];
个返回数据;
}
-(id)reverseTransformedValue:(id)value {
NSArray * array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [数组自动发布];
}
@end
@implementation NSDictionaryToDataTransformer
+(BOOL)allowsReverseTransformation {
return YES ;
}
+(Class)transformedValueClass {
return [NSData class];
}
-(id)transformedValue:(id)value {
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:value];
个返回数据;
}
-(id)reverseTransformedValue:(id)value {
NSDictionary * dict = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [dict autorelease];
}
@end
我的 Faktura
对象插入代码
-(void)fakturaCreator :( FakturaCreator *)form didEndWithValues:(NSDictionary *)values {
NSManagedObjectContext * context = [self.fetchedResultsControllermanagedObjectContext];
NSEntityDescription * entity = [[self.fetchedResultsController fetchRequest]实体];
Faktura * newFaktura = [NSEntityDescription insertNewObjectForEntityForName:[实体名称] 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 *错误=无;
if(![context save:& error]){
NSLog(@未解决的错误%@,%@,错误,[错误userInfo]);
abort();
}
[self.emptySectionView setHidden:YES];
}
FakturaCreator
是我的UIViewController,用户可以在其中创建发票。 values数组包含值的字典:我的发票编号( NSString
),各种日期( NSDate
),客户( NSDictionary
)和产品( NSArray
)。
请帮助我!
如果您需要一些其他代码,我会把它放在这里。
编辑:这是明确的 objectAtIndexPath:
错误。当我注释所有单元格设置代码(它将显示为空单元格),然后尝试删除该单元格时,应用程序在包含 objectatIndexPath:
的行上崩溃。
编辑#2:有人吗?请帮帮我...:(
我想我看到了问题。在您的 NSArrayToDataTransformer中
,您有这个:
-(id)reverseTransformedValue:(id)value {
NSArray * array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
返回[array autorelease];
}
由于 unarchiveObjectWithData:
并非以 alloc, new, copy或 mutableCopy开头,因此您不拥有该对象,并且因此可能无法自动发布它。您在 NSDictionaryToDataTransformer
中遇到相同的问题。
I have a huge problem with NSFetchedResultsCOntroller. I'm using fetchedResultsContrioller and I have interface with 3 tabs. They use Core Data too. But I have a problem with only ONE of them.
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
is my NSManagedObject subclass.
NSZombie says:
-[CFDictionary retain]: message sent to deallocated instance 0x5d619d0
My fetchedResultsController implementation:
- (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
My Faktura
object insertion code
- (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
is my UIViewController where user create an invoice. values array contains dictionary of values: my invoice number (NSString
), various dates (NSDate
), client (NSDictionary
) and products (NSArray
).
Please help me! If you want some additional code, i'll put it here.
EDIT: It is definetly objectAtIndexPath:
fault. When I comment all the cell setup code (it will display empty cell) and then try to remove the cell, app crashes on line which contains objectatIndexPath:
.
EDIT #2: Anybody? Please, help me... :(
I think I see the problem. In your NSArrayToDataTransformer
, you have this:
- (id)reverseTransformedValue:(id)value {
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
return [array autorelease];
}
Since unarchiveObjectWithData:
does not begin with "alloc", "new", "copy", or "mutableCopy", you do not own the object and therefore may not autorelease it. You have the same problem in your NSDictionaryToDataTransformer
.
这篇关于NSFetchedResultsController objectAtIndexPath崩溃(EXC_BAD_ACCESS)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!