2014-09-29 39 views
0

我在做什麼的總結。KVO - observeValueForKeyPath不被調用

我在我的AppDelegate.h中有一個名爲mailText的NSMutableString屬性,每當我更改此屬性的值時,我希望我的viewController得到通知,並將其本地IBOutlet屬性的值設置爲新值。最終,APpDelegate會根據收到的推送通知更改字符串。

爲了測試,我在APpDelegate中觸發一個計時器,並在計時器到期時更改mailText的值。然而,在我的viewController中的addObserver方法不被調用時發生這種情況

代碼在我AppDelegate.h

@property (strong, nonatomic) NSMutableString *mailText; 

守則AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 

    ...... 

    self.mailText = [NSMutableString string] ; 
    self.mailText = (NSMutableString *)@"First text" ; 

    [self enableTimer] ; 
    ...... 
} 

-(void) enableTimer 
{ 
    NSTimer *timer = nil ; 

    timer = [NSTimer scheduledTimerWithTimeInterval:30.0 target:self selector:@selector(updateText) userInfo:nil repeats:NO] ; 

    //self.myTimer = timer ; 

} 

-(void) updateText 
{ 
    self.mailText = (NSMutableString *)@"Changed to second text..aaanjanalnal .. jansjanskanska" ; 
    NSLog(@"Timer fired...updating mailtext") ; 

} 

觀察:當我在ViewController.m運行模擬器

代碼的應用程序在我ViewController.h

@interface MailDispViewController : UIViewController 

@property (weak, nonatomic) IBOutlet UITextView *mailDispText; 

@end 

代碼正在打印的NSLog的 「定時器解僱......」

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 

    [(AppDelegate *)[[UIApplication sharedApplication] delegate] addObserver:self forKeyPath:@"mailText" options:NSKeyValueObservingOptionNew context:nil]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 
{ 
    NSLog(@"received a KVO") ; 

    if ([keyPath isEqual:@"mailText"]) { 
     NSLog(@"received a KVO for mailtext") ; 
     self.mailDispText.text = [change objectForKey:NSKeyValueChangeNewKey]; 

    } 
    /* 
    Be sure to call the superclass's implementation *if it implements it*. 
    NSObject does not implement the method. 
    */ 
    [super observeValueForKeyPath:keyPath 
         ofObject:object 
          change:change 
          context:context]; 
} 

觀察:既不NSLogs 「接收的KVO」 並沒有被打印。

任何人都可以讓我知道我做錯了什麼嗎?

第二個問題,我如何從Xcode的調試窗口中找到存儲在mailText中的值。我試過郵件文本,但沒有奏效。

+0

發現問題... viewDidLoad未被調用.. – ArvindSN 2014-09-29 03:32:01

+0

在你的'-viewDidLoad'中放入一個日誌。它是否在定時器開火之前發生?順便說一句:你基本上從不使用可變類型的屬性;值屬性應該幾乎總是'copy'而不是'strong';你不能只將字符串文字轉換爲'NSMutableString *',並期望使它們變爲可變的;在分配另一個值之前立即將'[NSMutableString string]'分配給屬性,除了週期之外什麼也不做。 – 2014-09-29 03:32:05

+0

謝謝你。我認爲你的回答解釋了我所看到的下一個問題(當我回到主屏幕時崩潰)。你能否在初學者的術語中解釋關於可變字符串的部分?我是ObjectiveC新手,所有這些Mutable的東西對我來說都是新的,因爲我之前主要是C程序員。當我嘗試使用NSString時,當我在定時器到期後嘗試更改值時,我得到了一個EXC_BAD_ACCESS。那麼,如果我不能使用NSMutableString,我該如何更改字符串的值。 – ArvindSN 2014-09-29 03:51:13

回答

0

發現這個問題,MailDispViewController的viewDIdLoad從未被調用,因爲我從來沒有去過這個視圖。但是現在當我嘗試更新self.mailText到MailDispViewCOntroller並返回主視圖後,發生另一個問題(EXC_BAD_ACCESS)。

我禁止發佈圖片。所以我不能給屏幕截圖。因此,我會嘗試用文字解釋

主故事板由導航控制器(初始入口點)連接到兩個行的TableViewController組成。 TableViewCOntroller的第二行使用TextView連接到ViewController(我稱之爲下面的二級視圖)。

當我進入輔助視圖並回到主視圖時,當計時器到期並且MailText在我的AppDelegate中更新時,我得到一個EXC_BAD_ACCESS。如果我在計時器到期時保留在輔助視圖中,則沒有問題,並且我可以看到定時器到期後設置的更新文本。

誰能告訴我發生了什麼事?

+0

您需要在釋放視圖控制器之前刪除您在'-viewDidLoad'中設置的鍵值觀察值。 – 2014-09-29 15:12:12

+0

謝謝,但我想維護KVO ...即每當AppDelegate獲得有效載荷中新文本的新推送通知時,我都希望在從「主窗口」移動到「消息顯示器」時顯示新文本窗口」。我應該刪除KVO並再次添加嗎? – ArvindSN 2014-09-29 16:00:54

+0

如果有可能正在觀察的視圖控制器可能會被釋放,那麼您必須刪除觀察。如果您稍後創建新實例,則可以重新添加它,是的。 – 2014-09-29 17:11:53