__block变量更改值

时间:2014-04-10 00:35:37

标签: ios objective-c cocoa-touch objective-c-blocks

我正在尝试搜索提醒列表,以检查是否存在提醒。方法中有一个选项可以保存提醒是否存在的值。我正在使用一个块,并且在块中,当找到提醒时,新值被分配给reminderExists变量,就像它应该的那样。但是,当我输入save if语句时,reminderExists的值已从块中指定的值更改。我对这个问题很难过,我已经尝试了很多改变来诊断问题,但没有用。谢谢你的帮助!

- (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];

}

2 个答案:

答案 0 :(得分:5)

fetchRemindersMatchingPredicate:completion:的调用是异步的。这意味着此呼叫之后的if语句实际上是在fetchRemindersMatchingPredicate:completion:的呼叫完成之前很久就完成的。

在执行异步处理的方法中,您无法获得有用的返回值。您需要更改checkForReminderWithTitle:saveChanges:方法以返回void,而是让它通过一个完成块,在完成对fetchRemindersMatchingPredicate:completion:的调用后将调用该完成块。

顺便说一句 - 为什么reminderExistsNSNumber指针,而不仅仅是BOOL

答案 1 :(得分:1)

[EKEventStore fetchRemindersMatchingPredicate:completion:]的调用是异步的。因此,当您检查完成块下方reminderExists的值时,完成块可能尚未执行,reminderExists可能尚未具有正确的值。

要解决此问题,请将检查代码放在完成块的末尾。正如@rmaddy正确指出的那样,此函数无法返回值,因为它依赖于异步调用。