2012-05-28 4 views
8

특정 키에 대한 NSUserDefaults 값 변경 이벤트를 잡으려고하는 다음 코드를 작성했습니다.iOS NSUserDefaults 단일 키의 값 변경보기

[[NSUserDefaults standardUserDefaults] addObserver:self 
            forKeyPath:SOME_NSSTRING_VARIABLE 
             options:NSKeyValueObservingOptionNew 
             context:NULL]; 

- (void)observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context 
{NSLog (@"Changed for key %@", keyPath); } 

그러나 observeValueForKeyPath는 절대로 호출되지 않습니다. 심지어는 SOME_NSSTRING_VARIABLE을 Observing value changes to an NSUserDefaults key에서 언급 한 문자열로 대체하려고 시도했지만 도움이되지 않았습니다.

업데이트 : NSUserDefaults를 tabview에서 변경하고 있습니다. 위 코드는 변경 사항을 모니터링하기 위해 동일한 tabviewcontroller의 다른 탭에 있습니다. 내가 추가하면 내가 변경 (위의 코드가 존재하는 탭)에 대한 모니터 탭에서 :

- (void)viewWillAppear:(BOOL)animated 
{ 
[super viewWillAppear:animated]; 
// NSLog(@"viewillappear"); 
NSUserDefaults *FUDefaults = [NSUserDefaults standardUserDefaults]; 
NSLog(@"The username obtained is: %@", [FUDefaults objectForKey:SOME_NSSTRING_VARIABLE]); 
} 

업데이트 NSUserDefaults 값이 제대로 얻을 수 있지만, observeValueForKeyPath가 호출되지 않았습니다.

+0

당신이 변경 코드를 게시하시기 바랍니다 변수도 너무 – trapper

+0

또한 나는 그것을 가지고'[[NSUserDefaults st andardUserDefaults] addObserver ...'내부'viewDidLoad'? – trapper

+0

NSUserDefaults * FDefaults = [NSUserDefaults standardUserDefaults]; [FDefaults setObject : userName.text forKey : SOME_NSSTRING_VARIABLE]; [[NSUserDefaults 표준 사용자 정의]] 동기화]; –

답변

20

편집 : viewDidUnload 이제 사용되지 않습니다,이 완벽하게, 난 그냥 여기에 테스트 한 작업을해야 dealloc 대신

removeObserver에 사용합니다.

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    [[NSUserDefaults standardUserDefaults] addObserver:self 
              forKeyPath:@"SomeKey" 
               options:NSKeyValueObservingOptionNew 
               context:NULL]; 
    // Testing... 
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
    [defaults setObject:@"test" forKey:@"SomeKey"]; 
    [defaults synchronize]; 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 

    [[NSUserDefaults standardUserDefaults] removeObserver:self forKeyPath:@"SomeKey"]; 
} 

- (void)observeValueForKeyPath:(NSString *) keyPath ofObject:(id) object change:(NSDictionary *) change context:(void *) context 
{ 
    if([keyPath isEqual:@"SomeKey"]) 
    { 
     NSLog(@"SomeKey change: %@", change); 
    } 
} 

테스트 할 수있는 것.

  • 는 viewDidUnload에 브레이크 포인트를 넣어보기가 당신에 사라지고 있지 않은지 확인이 경우 어쩌면 레지스터 /에 코드를 드 등록하여 이동 (다른의 ViewController에서 SomeKey를 변경 이후부터) init/dealloc은 VC가 작동하는 방식에 따라 다릅니다.

  • 를 사용하여 명시 적으로 키 패스 @"SomeKey" 좋아하지 SOME_NSSTRING_VARIABLE

+0

저는 (시뮬레이터에서) 전체 전화를 재설정하고 빌드를 깨끗하게 처리했습니다. 이제 상황이 잘되고 있습니다. 귀하의 코드를 보내 주셔서 감사합니다. SOME_NSSTRING_VARIABLE도 함께 ​​작동합니다. –

+1

viewDidUnload가 더 이상 사용되지 않으며, 대신 dealloc을 사용하여 ObObserver를 사용합니다. – foOg

+0

예 변경되었습니다. – trapper

3

스위프트 버전과 같은 대체 :

func setUserDefaultsListener(){ 
     NSUserDefaults.standardUserDefaults().addObserver(self, forKeyPath: "keyPath", options: NSKeyValueObservingOptions.New, context: nil) 
    } 

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) { 
     if keyPath == "keyPath" { 
      //Do something 
     } 
    } 

    deinit { 
     NSUserDefaults.standardUserDefaults().removeObserver(self, forKeyPath: "keyPath") 
    } 
3

스위프트 3 버전 :

override func viewDidLoad() { 
    super.viewDidLoad() 
    UserDefaults.standard.addObserver(self, forKeyPath: "keyPath", options: .new, context: nil) 
} 

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 
    if keyPath == "keyPath" { 
     //Do something 
    } 
} 

deinit { 
    UserDefaults.standard.removeObserver(self, forKeyPath: "keyPath") 
}