Синглтон для получения CoreData, сбой на [fetchedResultsController_ PerformFetch:&error]

я создаю приложение для отправки OSC-сообщений через WLAN.
Вот почему у меня есть объект «Сеть» с одним объектом в нем. Из-за этого я хочу, чтобы Singleton извлекал этот объект.
В AppDelegate я создал метод класса для получения ManagedObjectContext.

static NSManagedObjectContext* manObCon;

@implementation...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
   manObCon = self.managedObjectContext;
...
}

+ (NSManagedObjectContext*) getManObCon{
   return manObCon;
}

manageObjectContext приходит с адресом в моем синглтоне, поэтому я думаю, что он должен работать.
Singleton.h (здесь ничего особенного)

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "OSC_iPadAppDelegate.h";
#import "Network.h";

@interface NetworkSingleton : NSObject <NSFetchedResultsControllerDelegate> {
}
+ (Network*) getNetwork;
+ (void) insertNewObject;
+ (NSFetchedResultsController *)fetchedResultsController;
@end

ПРИЛОЖЕНИЕ Singleton.m аварийно завершает работу в [fetchedResultsController_ performFetch:&error] с

warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1 (8C148)/Symbols/usr/lib/info/dns.so (file not found).
Program received signal:  “EXC_BAD_ACCESS”.
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1 (8C148)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).
kill
quit

Вот код Singleton.m

#import "NetworkSingleton.h"
static Network* _network;
static NSFetchedResultsController *fetchedResultsController_;
static NSManagedObjectContext *managedObjectContext_;

@implementation NetworkSingleton

+ (Network*) getNetwork{
    managedObjectContext_ = [OSC_iPadAppDelegate getManObCon]; //get the managedObjectContex from AppDelegate
//fetchedResultsController init
    fetchedResultsController_ = [NetworkSingleton fetchedResultsController]; //get fetchedResultsController 
//check if _network is set
    if (_network == nil) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController_ sections] objectAtIndex:0];
//if not set, check if there is already an network object in coredata
        if ([sectionInfo numberOfObjects] == 0) {
            //Create new Networkobject, if no one is existing
            [NetworkSingleton insertNewObject];
            fetchedResultsController_ = nil;
        }
//set _network
        _network = [fetchedResultsController_ objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    }
    return _network;
}

+ (NSFetchedResultsController *)fetchedResultsController {

    if (fetchedResultsController_ != nil) {
        return fetchedResultsController_;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Network" inManagedObjectContext: managedObjectContext_];
    [fetchRequest setEntity:entity];

    [fetchRequest setFetchBatchSize:1];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"sourcePort" ascending:YES selector:nil];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext_ sectionNameKeyPath:nil cacheName:nil];
    aFetchedResultsController.delegate = self;
    fetchedResultsController_ = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptors release];

    NSError *error = nil;
    /*
     APP CRASHES HER
     */
    if (![fetchedResultsController_ performFetch:&error]) { 
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

    return fetchedResultsController_;
}    
@end

Поэтому я не знаю, почему fetchedResultsController_ не делает то, что он делает лучше всего - fetch
это не ноль, но я не могу понять сообщение об ошибке и ничего не нашел в Google или где-то еще.
Проблема может быть в том, что мне нужно инициировать fetchedResultsController самостоятельно, потому что он не инициализируется автоматически, как в сгенерированных контроллерах представления.

Спасибо за помощь


person Seega    schedule 11.03.2011    source источник
comment
Это плохой дизайн. FetchedResultsController предназначен для использования в качестве контроллера между уровнем модели Core Data и уровнем представления UITableView. Это противоречит цели FRC, заключающейся в том, чтобы он удерживался объектом одноэлементной модели. Вы разбили свою модель и слои управления вместе и жестко запрограммировали табличное представление для данных.   -  person TechZen    schedule 11.03.2011
comment
В этом случае я не использую его как TableView. Мне нужен синглтон, потому что я использую данные во многих классах, которые не являются представлениями. Но как я могу сохранить один экземпляр без CoreData?   -  person Seega    schedule 15.03.2011


Ответы (1)


NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext_ sectionNameKeyPath:nil cacheName:nil];

fetchedResultsController_ = aFetchedResultsController;

[aFetchedResultsController release];

Когда вы используете fetchedResultsController_ после этого блока кода, он уже освобождается. Потому что вы его выделили (retainCount+1), а затем освободили (retainCount-1). Вы не сохранили, когда назначали aFetchedResultsController для fetchedResultsController_.

либо оставьте так fetchedResultsController_ = [aFetchedResultsController retain];
, либо удалите строку [aFetchedResultsController release];


РЕДАКТИРОВАТЬ: я только что увидел, что в вашем коде может быть больше ошибок.

Вы должны заменить все fetchedResultsController_ за пределами геттера fetchedResultsController на self.fetchedResultsController. Обычно _ позади или перед переменной должно говорить вам, что вы должны использовать сеттер и геттер, если вы не уверены, что делаете.

И fetchedResultsController_ = [NetworkSingleton fetchedResultsController]; вызывает fetchedResultsController_ = aFetchedResultsController;.
Что может сработать, но я бы этого не сделал.

person Matthias Bauch    schedule 11.03.2011
comment
[aFetchedResultsController release]; была проблема, к проблеме self.fetchedResultsController, _ символы, что атрибут является закрытым, и я просто использую его в самом классе, так что это не проблема - person Seega; 11.03.2011