NSFetchedResultsController objectAtIndexPath崩溃(EXC_BAD_ACCESS) [英] NSFetchedResultsController objectAtIndexPath crash (EXC_BAD_ACCESS)

查看:49
本文介绍了NSFetchedResultsController objectAtIndexPath崩溃(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆