Переменная экземпляра равна нулю при доступе из блока

Я использую API EventKit для получения напоминаний пользователя. API выборки выполняется асинхронно, и когда выборка завершена, вы можете использовать блок завершения. Однако после того, как я получил напоминания пользователя, я назначаю их переменной экземпляра self.eventKitReminderEvents (я отладил и увидел, что это не ноль). Затем сразу после того, как я вызываю блок, но внутри этого блока self.eventKitReminderEvents имеет значение nil. Я не очень понимаю, почему это происходит. Может быть, кто-то может взглянуть на мой код и дать мне ключ.

Я использую API следующим образом:

- (void)futureReminders {

    dispatch_semaphore_t sema = dispatch_semaphore_create(0);

    [self fetchReminderEventsInBackgroundFromDate:[NSDate date] withCompletionBlock:^{

        // When I enter here self.eventKitReminderEvents is nil
        // Which is weird because it should be set already if you look in
        // fetchReminderEventsInBackgroundFromDate below...

        [self processEventKitRemindersWithCompletion:^(NSArray *reminderEvents) {

            // Save a copy in memory
            self.futureReminderEvents = reminderEvents;

            // Send a signal that indicates that this asynchronous task is completed ...
            dispatch_semaphore_signal(sema);
         }];
    }];

    // Wait for dispatch signal
    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);

}

- (void)fetchReminderEventsInBackgroundFromDate:(NSDate *)startDate withCompletionBlock:(void(^)(void))block {

    DLogName()

    //NSDate *startDate = [NSDate date];
    NSDate *endDate = [NSDate distantFuture]; // This will get me events 4 years from now

    // Create the predicate
    NSPredicate *predicate = [self.eventStore predicateForIncompleteRemindersWithDueDateStarting:startDate ending:endDate calendars:nil];

    [self.eventStore fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) {

        self.eventKitReminderEvents = reminders;
        block();
    }];
}

person Peter Warbo    schedule 13.02.2013    source источник
comment
Покажите код, как вы создали переменную экземпляра, или это просто ивар?   -  person Anoop Vaidya    schedule 13.02.2013
comment
@AKV Это просто свойство NSArray - @property (nonatomic, strong) NSArray *eventKitReminderEvents;   -  person Peter Warbo    schedule 13.02.2013
comment
Не уверен, по крайней мере, попробуйте, вставив его в { и }.   -  person Anoop Vaidya    schedule 13.02.2013
comment
ивары старого образца. @implementation { NSString *string; } @end Сюда.   -  person Anoop Vaidya    schedule 13.02.2013
comment
Вы уверены, что self.eventKitReminderEvents правильно установлен перед вызовом block(); ? Вы пытались NSLog это?   -  person LombaX    schedule 13.02.2013
comment
@LombaX да, проверьте код, который я предоставил...   -  person Peter Warbo    schedule 14.02.2013
comment
Я попробовал ваш код (удалив processEventKitRemindersWithCompletion, потому что я не знаю реализацию :-), и в моем случае self.eventKitReminderEvents установлен правильно. В этот момент я бы искал проблему за пределами этого кода... попытался переопределить установщик для eventKitReminderEvents и посмотреть, не устанавливает ли что-то значение nil перед входом в блок (при условии, что он использует установщик, а не переменную экземпляра напрямую... )   -  person LombaX    schedule 14.02.2013


Ответы (2)


Вам нужно создать selfInBlock, чтобы убедиться, что вы не потеряете ссылку на себя внутри блока, подобного этому

__block YourSelfClassName *selfInBlock = self;

и используйте selfInBlock вместо self внутри блока.

person Radu    schedule 13.02.2013
comment
какие? это не имеет смысла. __block полезен только тогда, когда переменная назначена где-то или в MRC, чтобы предотвратить ее сохранение в блоке. Ни одна из этих вещей здесь не актуальна - person newacct; 14.02.2013
comment
я неправильно понял вопрос. - person Radu; 14.02.2013

Спасибо за все ответы/комментарии, которые я получил. Я только что заметил, что на самом деле устанавливал другую переменную экземпляра с похожим именем, поэтому оно было равно нулю.

Примечание для себя: будьте очень осторожны при копировании и вставке кода :)

person Peter Warbo    schedule 14.02.2013