Как вызвать метод @dynamic объекта NSManaged из другого объекта, используя @selector и NSInvocation?

Какао новичок здесь. Я работаю над виджетом на основе iPhone UITableViewController, который можно использовать для редактирования свойств даты и текста в наборе объектов во время инициации. В настоящее время я пытаюсь сделать это с помощью @selector и NSInvocation, как показано ниже. Примечание: targetObject — это объект, установленный при инициализации контроллера.

- (IBAction)saveDate:(id)sender {
      //The selector below would normally be passed in when the controller is initialized
      [self setDoneSelector:@selector(setDate:)];
      NSMethodSignature * sig = nil;
      sig = [[targetObject class] instanceMethodSignatureForSelector:[self doneSelector]];
      NSInvocation * myInvocation = nil;
      myInvocation = [NSInvocation invocationWithMethodSignature:sig];
      [myInvocation setTarget:targetObject];
      [myInvocation setSelector:doneSelector];
      NSDate * myDate = [datePicker date];
      [myInvocation setArgument:&myDate atIndex:2];
      NSString * result = nil; 
      [myInvocation retainArguments]; 
      [myInvocation invoke];
}

Это отлично работает для большинства объектов, но у меня возникают проблемы при передаче основных данных (NSManagedObject) в качестве целевого объекта. Объект выглядит так:

Транзакция.ч

#import <CoreData/CoreData.h>

@interface Transaction :  NSManagedObject  
{
}

@property (nonatomic, retain) NSString * message;
@property (nonatomic, retain) NSDate * date;

@end

Транзакция.м

#import "Transaction.h"

@implementation Transaction 

@dynamic message;
@dynamic date;

@end

Если я установлю этот объект в своем контроллере как targetObject, я могу напрямую вызвать метод setDate: без проблем.

[targetObject setDate:[datePicker date]];

Но когда я пытаюсь вызвать его с помощью @selector, я получаю «Программа получила сигнал: «EXC_BAD_ACCESS».

Я предполагаю, что это как-то связано с методами @dynamic, используемыми в NSManagedObject, и когда они создаются, но я недостаточно знаю об этом процессе, чтобы знать, как это сделать или могу ли я обойти это, чтобы заставить его работать. Я попытался явно создать метод «setDate: (NSDate *) aDate» в объекте Transaction, и это работает, но мне интересно, должен ли я это делать и как это может привести к NSManagedObject.

Могу ли я получить доступ к этим методам установки с помощью @selector без их явного определения?


person kevindayton    schedule 15.10.2009    source источник
comment
Почему для этого нужно использовать NSInvocation?   -  person Azeem.Butt    schedule 15.10.2009
comment
Чтобы уточнить: каким образом семейство сообщений NSObject PerformSelector не соответствовало вашим потребностям? Очень немногим людям когда-либо приходилось использовать NSInvocation, и я не вижу причин, по которым вы могли бы быть одним из них из этого фрагмента.   -  person Azeem.Butt    schedule 15.10.2009


Ответы (1)


Договорились с NSD здесь. Вы должны начать с упрощения этого кода до гораздо более простой версии -performSelector:withObject::

- (IBAction)saveDate:(id)sender {
      [self.targetObject performSelector:self.doneSelector withObject:[self.datePicker date]];
}

Если с этим все еще есть проблемы, мы можем начать отладку там, где настоящая проблема. NSInvocation — очень причудливый объект для решения такой простой задачи.

Если вы все еще получаете сбой, вам нужно посмотреть на фактическую трассировку стека, чтобы увидеть, какая переменная неправильно инициализируется или перевыпускается.

person Rob Napier    schedule 15.10.2009
comment
Прикомандирован. И EXEC_BAD_ACCESS почти всегда вызывает метод для освобожденного объекта. (Может быть, указатель, который пережил свой контекст управляемого объекта или что-то в этом роде?) - person Sixten Otto; 15.10.2009
comment
Ничего себе, я не могу поверить, что не копнул немного глубже, чтобы найти гораздо более простой метод. Это казалось слишком сложным, но я застрял на NSInvocation. Этот метод устраняет ошибку EXC_BAD_ACCESS. Простой, элегантный и рабочий. Мне это нравится! Спасибо вам всем. - person kevindayton; 15.10.2009