CoreData и NSInvalidArgumentException нераспознанный селектор, отправленный на экземпляр - PullRequest
3 голосов
/ 30 января 2012

Я продолжаю сталкиваться с этим исключением, когда пытаюсь установить свое свойство "phoneNumber":

* Завершение работы приложения из-за необработанного исключения 'NSInvalidArgumentException', причина: '- [SearchResult setPhoneNumber:]: нераспознанный селектор отправлен на экземпляр 0x256b40 '

Вот класс со свойством phoneNumber:

@interface SearchResult : NSManagedObject
@property (nonatomic, retain) NSString * phoneNumber;
@end

@implementation SearchResult
@dynamic phoneNumber;
@end

Проблема заключается в том, что когда я делаю это:

SearchResult *managedObject = [self findExistingSearchResultById:restaurantId];

if(managedObject == nil)
{ 
    managedObject = [NSEntityDescription insertNewObjectForEntityForName:@"SearchResult" inManagedObjectContext:managedObjectContext];
}

// Exception throws here.
managedObject.phoneNumber = @"1234567890";

Вотметод findExistingSearchResult:

+ (SearchResult *)findExistingSearchResultById:(NSString *)restaurantId
{
    NSManagedObjectContext *managedObjectContext = serviceContext;
    NSFetchRequest *request = [[NSFetchRequest alloc]init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"SearchResult" inManagedObjectContext:managedObjectContext];
    [request setEntity:entity];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"restaurantId = %@", restaurantId];
    [request setPredicate:predicate];

    NSError *error = nil;
    NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:request error:&error];
    if(fetchedObjects != nil)
    {
        return [fetchedObjects lastObject];
    }
    else
    {
        return nil;
    }
}

Я использую очень похожие реализации классов в своем приложении и не сталкиваюсь с такими проблемами.Я не понял, почему установка свойства phoneNumber здесь вызывает это исключение.

Ответы [ 3 ]

6 голосов
/ 30 января 2012

Проблема в том, что вы пытаетесь создать экземпляр NSManagedObject с использованием обычного метода alloc / init NSObject.

Если вы хотите использовать CoreData, вы должны использовать назначенный инициализатор NSManagedObject, как описано в справочной документации по классам для NSManagedObject

NSManagedObject - универсальный класс, который реализует все основные требуется поведение объекта модели Core Data. Не возможно использовать экземпляры прямых подклассов NSObject (или любого другого класса, не наследование от NSManagedObject) с контекстом управляемого объекта. Вы может создавать пользовательские подклассы NSManagedObject, хотя это не всегда требуется. Если никакой специальной логики не требуется, полный граф объектов может быть сформирован с экземплярами NSManagedObject.

Управляемый объект связан с описанием объекта (экземпляр NSEntityDescription), который предоставляет метаданные об объекте (включая имя объекта, который представляет объект, и имена его атрибутов и отношений) и с управляемым объектом контекст, который отслеживает изменения в графе объекта. Это важно что управляемый объект правильно настроен для использования с базовыми данными. если ты создать экземпляр управляемого объекта напрямую, необходимо вызвать инициализатор (initWithEntity: insertIntoManagedObjectContext:).

Источник: http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/Reference/NSManagedObject.html

2 голосов
/ 20 апреля 2012

У меня была та же проблема, и я не смог ее решить. В конечном итоге я удалил свойство из файла xcdatamodel, затем снова добавил его, очистил и перестроил. Наконец сработало после того, как многие другие вещи потерпели неудачу.

0 голосов
/ 30 января 2012

Вы помещаете это в свой интерфейс:

@property (nonatomic, retain) NSString * phoneNumber;

Это означает, что ваша реализация должна предоставлять два метода, phoneNumber и setPhoneNumber:.

Вы помещаете это в свою реализацию:

@dynamic phoneNumber;

Это говорит компилятору, что you позаботится о том, чтобы методы phoneNumber и setPhoneNumber: существовали во время выполнения, поэтому компилятор не должен предупреждать вас о том, что они не найдены.

Замените оператор @dynamic следующим:

@synthesize phoneNumber;

Это говорит компилятору генерировать для вас методы phoneNumber и setPhoneNumber: и генерировать личную переменную экземпляра длядержать значение свойства.

...