2014-04-10 92 views
0

我試圖通過提醒列表進行搜索以檢查提示是否存在。方法中有一個選項可以保存提醒是否存在的值。我正在使用一個塊,並在該塊內找到提醒時,將新值分配給reminderExists變量,就像它應該的那樣。但是,當我輸入save if語句時,reminderExists的值已從塊中分配的值更改。我很困惑這個問題,並且我已經嘗試了很多變化來診斷問題,但沒有用。謝謝你的幫助!__block變量更改值

- (BOOL)checkForReminderWithTitle:(NSString *)reminderTitle saveChanges:(BOOL)save { 

NSNumber *currentGardenCurrentReminders = currentGarden.reminders; 
__block NSNumber *reminderExists = [NSNumber numberWithBool:NO]; 

if (eventStore == nil) 
{ 
    eventStore = [[EKEventStore alloc] init]; 

    [eventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error) { 

     if (!granted) 
      NSLog(@"Access to store not granted"); 
    }]; 
} 


if (eventStore != nil) { 

    NSPredicate *predicate = [eventStore predicateForIncompleteRemindersWithDueDateStarting:[NSDate distantPast] ending:[NSDate distantFuture] calendars:[NSArray arrayWithObject:[eventStore defaultCalendarForNewReminders]]]; 

    [eventStore fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) { 
     for (EKReminder *reminder in reminders) { 

      NSLog(@"%@", reminderTitle); 

      if ([reminder.title isEqualToString:reminderTitle]) { 

       reminderExists = [NSNumber numberWithBool:YES]; 
       NSLog(@"reminder exists"); 
       NSLog(@"after reminder exists is assigned to YES, value is %@", ([reminderExists boolValue]) ? @"True" : @"False"); 
       if ([reminderExists boolValue]) NSLog(@"reminder exists variable works"); 

       NSArray *alarms = reminder.alarms; 

       EKAlarm *alarm = [alarms objectAtIndex:0]; 

       NSDateFormatter *nextReminderDateFormatter = [[NSDateFormatter alloc] init]; 
       nextReminderDateFormatter.dateFormat = @"MM/dd/yyyy at hh:mm a"; 
       NSString *nextReminderDateString = [nextReminderDateFormatter stringFromDate:alarm.absoluteDate]; 

       NSLog(@"Next reminder is on %@", nextReminderDateString); 

       break; 

      } 
     } 
    }]; 

} 

if (save && ([currentGardenCurrentReminders boolValue] != [reminderExists boolValue])) { 

    if ([reminderExists boolValue]) { 
     NSLog(@"within save, reminderexists == true"); 
    } else NSLog(@"within save, reminderexists == false"); 

    currentGarden.reminders = reminderExists; 
    [self.managedObjectContext save:nil]; 
} 

return [reminderExists boolValue]; 

}

回答

5

fetchRemindersMatchingPredicate:completion:的調用是異步的。這意味着在撥打fetchRemindersMatchingPredicate:completion:之前,您的if聲明實際上已經完成。

在執行異步處理的方法中不能有有用的返回值。您需要更改您的checkForReminderWithTitle:saveChanges:方法以返回void,而是讓它通過一個完成塊,在完成對fetchRemindersMatchingPredicate:completion:的呼叫時將會調用該塊。

順便說一句 - 爲什麼是reminderExists一個NSNumber指針,而不僅僅是一個BOOL

+0

'reminderExists'最初是'BOOL',然而,在調試過程中,我認爲不使用對象可能是問題的一部分。 – Andrew

+0

我已經在塊中移動了'if(save)'語句,但是,如果我的'for'循環從未找到提醒,我將如何執行保存? – Andrew

+0

如果'eventStore == nil',則需要相同的「保存」代碼。創建一個具有相同邏輯的方法,您可以從需要從其調用的兩個位置調用該方法。 – rmaddy

1

[EKEventStore fetchRemindersMatchingPredicate:completion:]呼叫是異步的。因此,當您在完成塊下面檢查reminderExists的值時,完成塊可能尚未執行,並且reminderExists可能尚未具有正確的值。

要解決該問題,請將檢查代碼放在完成塊的末尾。正如@rmaddy指出的那樣,該函數不能返回值,因爲它依賴於異步調用。

+0

簡單地在塊內移動if語句並不能解決這個方法試圖返回一個異步計算的值的事實。 – rmaddy

+0

@rmaddy你是正確的先生。我只是澄清了我的答案。 – Macondo2Seattle