0

안녕 동료 아이폰 개발자,아이폰 키 - 값 옵서버 : 관찰자 내가 아이폰 플랫폼에 대한 경험이 풍부한 소프트웨어 엔지니어하지만 새로운 오전있는 UITableViewController

에 등록하지. 서브 클래 싱 된 뷰 컨트롤러를 성공적으로 구현했으며 뷰 컨트롤러 스택에서 부모/자식 뷰를 밀고 팝 할 수 있습니다. 그러나 개체 뷰 뷰 컨트롤러에서 개체를 편집 할 때보기 컨트롤러를 업데이트하는 동안 문제가 발생했습니다. 많은 실험을 거치지 않은 후에 키 - 값 관찰자 API를 발견했습니다.이 API는이를 수행하는 완벽한 방법으로 보입니다. 그런 다음 주/부모보기 컨트롤러에 관찰자를 등록하고 관찰자에서보기를 다시로드하려고합니다. 아이디어는 자식보기 컨트롤러에서 개체를 편집 할 때 해고됩니다. 그러나, 나는 그 값이 편집 뷰 컨트롤러 (디버거에서 볼 수 있음)에서 업데이트된다는 것을 알고 있기 때문에 관찰자가 등록되지 않았다고 생각합니다. 그러나 관찰 방법은 절대로 호출되지 않습니다.

도와주세요!

코드 조각은 다음과 같습니다.

관찰 대상. 이 값은 setvalue 메시지 (아래의 Child View Controller 참조)를 사용하여 호출 할 때 값이 설정되므로 키 - 값을 준수한다고 생각합니다.

X.h :

@interface X : NSObject <NSCoding> { 
    NSString *name; 
... 
@property (nonatomic, retain) NSString *name; 

X.m :

@implementation X 

@synthesize name; 
... 

홈페이지보기 Controller.h :

@class X; 

@interface XViewController : UITableViewController { 
    X *x; 
... 

홈페이지보기 Controller.m :

@implementation XViewController 

@synthesize x; 
... 
- (void)viewDidLoad { 
    ... 
    [self.x addObserver:self 
      forKeyPath: @"name" 
      options:  (NSKeyValueObservingOptionNew | 
          NSKeyValueObservingOptionOld) 
      context:nil]; 

    [super viewDidLoad]; 
} 
... 
- (void)observeValueForKeyPath:(NSString *)keyPath 
        ofObject:(id)object 
        change:(NSDictionary *)change 
        context:(void *)context 
{ 
    if ([keyPath isEqual:@"name"]) { 
     NSLog(@"Found change to X"); 
    [self.tableView reloadData]; 
    } 

    [super observeValueForKeyPath:keyPath 
      ofObject:object 
      change:change 
      context:context]; 
} 

아이보기 Controller.m는 : forKeyPath : 당신이 addObserver를 호출하기 전에 viewDidLoad에()에서 X 개체를 인스턴스화하는 경우

[self.x setValue:[[tempValues objectForKey:key] text] forKey:@"name"]; 

답변

0

당신은 확인 했나 (이 올바르게 아이 뷰 컨트롤러에서 개체의 값을 설정) 옵션을 : 컨텍스트 :? x 객체는 이미 할당되었거나 초기화되어야합니다.

사소한 고려 사항. context 매개 변수는 (void *)로 선언 되었기 때문에 NULL이 아닌 nil (null은 NULL을 나타내는 null 객체 포인터, 0은 (void *) 0)을 전달해야합니다. Objective C에서는 널 (null) 클래스 포인터를 나타내는 nil, NULL 및 Nil을 구별해야합니다.

+0

결함을 지적 해 주셔서 감사합니다. 난 내가 대신 아이 뷰 컨트롤러 인스턴스 변수 특성에 관찰자를 넣어 경우 이벤트가 발생 얻을 수 있다는 것을 발견했다 (!). 즉, 편집 버튼을 누를 때, 나는이 수행 위의 예에서, : 홈페이지보기 Controller.m ... ChildViewController.x = self.x; [ChildViewController.x \t addObserver : 자기 \t \t \t \t \t forKeyPath : (NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) 컨텍스트 : "이름" 옵션 @ \t NULL] [자기있는 navigationController]과 pushViewController : ChildViewController 애니메이션 : YES]; 은 ... – Scott

0

키 값 관측은 응용 프로그램에서 잘 작동하지만 알림 센터를 사용하면 "주요"보기 컨트롤러간에 통신하는 것이 더 좋습니다. ("주요"보기 컨트롤러는 iPhone의 전체 화면보기를위한 주 컨트롤러입니다.)

이렇게하면 통신이 발생할 때 두보기 컨트롤러가 모두 존재하게됩니다. KVO는 공통된 상황, 즉 단일보기 컨트롤러 또는 모델에서 사용되도록 설계된 것 같습니다.

클래스 X는 KVC 규격 인 것처럼 보입니다. 코드에서 @property를 선언하는지 여부는 표시하지 않지만 나는 네가 그렇게한다고 가정 할 것이다.

왜 이러는 :

[self.X의 setValue : [[tempValues ​​objectForKey : 키] 텍스트] forKey : "이름"@] 당신의 아이 뷰 컨트롤러에서

보다는 :

self.name = [[tempValues ​​objectForKey : 키] 텍스트]

(그리고 당신은 정말 위 self.X을 의미 않았다 self.X이 self.x.되지 않는 이유는 무엇입니까?)

또 다른 메모 : 당신이 당신의 슈퍼 클래스를 호출 할 필요가 없습니다 - [observeValueForKeyPath : ofObject을 : 변화를 : context :] 메소드를 호출합니다.

앤드류

+0

내가 슈퍼 클래스를 호출 할 필요가 없다는 지적 주셔서 감사합니다. 일단 이벤트가 발생하면 예외가 발생했습니다. 그러나, 코드 self.x.name = [온도와 .. [self.x의 setValue의 ...는 (I 모두 시험) 실제로 기능적으로 동등하다. 하나가 다른 것보다 더 효율적인지 확신 할 수 없지만 대안을 제시해 주셔서 감사합니다. KVO 설명서를 읽으면서 [self.x setValue ... 구문이 필요하다고 생각했습니다. – Scott