NSFetchedResultsController objectAtIndexPath crash (EXC_BAD_ACCESS) - PullRequest
1 голос
/ 03 мая 2011

У меня огромная проблема с NSFetchedResultsCOntroller.Я использую fetchedResultsContrioller и у меня есть интерфейс с 3 вкладками.Они тоже используют Core Data.Но у меня проблема только с одним из них.

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.

NSZombie говорит: -[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;
} 

Фактура.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

Фактура.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).

Пожалуйста, помогите мне!Если вам нужен дополнительный код, я добавлю его сюда.

РЕДАКТИРОВАТЬ: Это определенно objectAtIndexPath: ошибка.Когда я комментирую весь код установки ячейки (он будет отображать пустую ячейку), а затем пытаюсь удалить ячейку, приложение вылетает в строке, содержащей objectatIndexPath:.

РЕДАКТИРОВАТЬ # 2: Anybody?Пожалуйста, помогите мне ...: (

Ответы [ 2 ]

2 голосов
/ 08 мая 2011

Мне кажется, я вижу проблему. В вашем NSArrayToDataTransformer, у вас есть это:

- (id)reverseTransformedValue:(id)value {
    NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:value];
    return [array autorelease];
}

Поскольку unarchiveObjectWithData: не начинается с «alloc», «new», «copy» или «mutableCopy», вы не являетесь владельцем объекта и, следовательно, не можете автоматически его высвобождать. У вас такая же проблема в вашем NSDictionaryToDataTransformer.

1 голос
/ 04 мая 2011

Ваше включение преобразователей значения в класс и использование +initialize не является стандартным. Хотя +initialize должно работать, в документации по основным данным рекомендуется вообще не использовать какие-либо методы инициализации, а полагаться на awakeFromFetch для инициализации.

Я бы проверил ваши методы табличного представления, такие как numberOfRowsInSection:, чтобы убедиться, что вы получаете правильные индексы из табличного представления. Если строки в табличном представлении и счетчике массива fetchedObjects не синхронизированы, вы можете получить такой вид сбоя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...