2009-10-15 4 views
0

코코아 새내기는 여기에 있습니다. 내가 시작하는 동안 설정된 객체의 날짜 및 텍스트 속성을 편집하는 데 사용할 수있는 iPhone UITableViewController 기반 위젯에 대해 작업하고 있습니다. 현재, 아래와 같이 @selector 및 NSInvocation을 사용하여이 작업을 시도하고 있습니다. 참고 : "targetObject"는 컨트롤러가 초기화 될 때 설정된 객체입니다.@selector와 NSInvocation을 사용하여 다른 개체에서 NSManaged 개체의 @dynamic 메서드를 호출하려면 어떻게해야합니까?

- (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)를 targetObject로 전달할 때 문제가 있습니다. 목적은 다음과 같습니다

Transaction.h

#import <CoreData/CoreData.h> 

@interface Transaction : NSManagedObject 
{ 
} 

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

@end 

에게 Transaction.m

#import "Transaction.h" 

@implementation Transaction 

@dynamic message; 
@dynamic date; 

@end 

을 나는 targetObject으로 내 컨트롤러에서이 객체를 설정하면, 내가 호출 할 수 있습니다 "하여 setDate을" 메서드를 직접 문제없이 사용하십시오.

[targetObject setDate:[datePicker date]]; 

그러나 내가 @ 선택기로 호출 할 때, 내가 할 '프로그램은 신호를 수신 :. "EXC_BAD_ACCESS"를'

이것은 NSManagedObject에서 사용 된 @dynamic 메소드와 관련이 있다고 상상해 봅니다. 그러나 NSManagedObject를 생성 할 때 그 메소드에 대해 충분히 알지 못합니다. 명시 적으로 "setDate : (NSDate *) aDate"메서드를 트랜잭션 개체에 만들려고했는데 작동하지만 그 작업을 수행해야하는 경우 그리고 NSManagedObject가 어떻게 될지 궁금합니다.

@selector를 명시 적으로 정의하지 않고 setter 메서드를 사용하면됩니다.

+0

왜 NSInvocation을 사용해야합니까? –

+1

명확히하기 : NSObject의 performSelector 메시지 패밀리가 고객의 요구에 부적합한 방법은 무엇입니까? NSInvocation을 사용할 필요가있는 사람은 극히 드물며,이 스 니펫에서 왜 당신이 그 중 한 명일 수는 없는지는 알 수 없습니다. –

답변

1

여기 NSD와 동의합니다.이 코드를 훨씬 간단하게 -performSelector:withObject: 버전으로 단순화하면됩니다.

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

그래도 문제가 발생하면 실제 문제가있는 곳에서 디버깅을 시작할 수 있습니다. NSInvocation은 이런 종류의 간단한 문제를 해결하기위한 매우 멋진 목표입니다.

여전히 크래시가 발생하면 실제 스택 추적을보고 어떤 변수가 올바르게 초기화되지 않았는지 또는 과도하게 공개되지 않는지 확인하는 것이 좋습니다.

+0

Seconded. 그리고 EXEC_BAD_ACCESS는 거의 항상 릴리스 된 객체에 대한 메소드를 호출합니다. (어쩌면 그 매니지드 오브젝트 컨텍스트 나 그 이상으로 끝난 포인터 일까?) –

+0

와우, 훨씬 간단한 방법을 찾기 위해 조금 더 깊이 파지 못했다고 나는 믿을 수 없다. 지나치게 복잡해 보였지만 NSInvocation에 잠겨 있습니다. 이 방법은 EXC_BAD_ACCESS 오류를 제거하는 것으로 보입니다. 간단하고 우아하며 작동합니다. 나는 그것을 좋아한다! 모두에게 감사드립니다. – kevindayton

관련 문제