我同時運行兩個不同的dispatch queues
,循環遍歷365次迭代並實例化一個對象。該循環將該對象添加到NSNotificationCenter
,然後該對象在完成事件存儲區異步代碼塊後發佈通知。我的問題是,我應該在調試器中收到730條消息,但我不知道。每次運行應用程序時,我都會收到不同數量的消息,從513到630.NSNotificationCenter observer收到不同數量的每次運行的通知
是否有任何理由解釋這種情況?
這是我執行循環的代碼,並將對象添加到Notification Center
。我創建了一個HZCalendarDay
的實例,我將它添加到一個不可變數組中。
- (id)init {
self = [super init];
if (self) {
// Alloc/Init instance variables.
previousDays = [[NSMutableArray alloc] init];
futureDays = [[NSMutableArray alloc] init];
self.datesOnCalendar = [[NSMutableArray alloc] init];
self.stateOfCalendarCache = StateOfEventStoreCache_CachingRequired;
self.currentDay = [[HZCalendarDay alloc] init];
// Setup our event store security access.
[self setupEventStore];
DEDateUtility *dateUtility = [[DEDateUtility alloc] init];
NSDate *today = [dateUtility normalizedDateWithDate:[NSDate date]];
HZCalendarDay *date = [[HZCalendarDay alloc] initOnDate:today withEventStore:self.eventStore];
[self.datesOnCalendar addObject:date];
self.currentDay = date;
// Before we start caching, we need to setup the KVO so we can compile the
// completed caches, since both previous and future days are cached separately.
// Start caching previous days.
dispatch_queue_t previousDaysCacheQueue = dispatch_queue_create("previousDaysCacheQueue", NULL);
dispatch_async(previousDaysCacheQueue,^{
int numberOfDays = (HZ_NUMBER_OF_TOTAL_YEARS_TO_CACHE * 365)/2;
for (int count = 1; count < numberOfDays; count++) {
NSDate *previousDate = [dateUtility adjustDate:today byNumberOfDays:-count];
HZCalendarDay *calendarDay = [[HZCalendarDay alloc] initOnDate:previousDate withEventStore:self.eventStore];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(completeCaching:) name:HZ_KVO_CALENDAR_CACHE_NOTIFICATION object:calendarDay];
@synchronized (self.datesOnCalendar) {
[self.datesOnCalendar insertObject:calendarDay atIndex:0];
}
}
});
// Start caching future days.
dispatch_queue_t futureDaysCacheQueue = dispatch_queue_create("futureDaysCacheQueue", NULL);
dispatch_async(futureDaysCacheQueue,^{
int numberOfDays = (HZ_NUMBER_OF_TOTAL_YEARS_TO_CACHE * 365)/2;
for (int count = 1; count < numberOfDays; count++) {
NSDate *futureDate = [dateUtility adjustDate:today byNumberOfDays:count];
HZCalendarDay *calendarDay = [[HZCalendarDay alloc] initOnDate:futureDate withEventStore:self.eventStore];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(completeCaching:) name:HZ_KVO_CALENDAR_CACHE_NOTIFICATION object:calendarDay];
@synchronized (self.datesOnCalendar) {
[self.datesOnCalendar addObject:calendarDay];
}
};
});
}
return self;
}
在同一個班級,我有我的NSNotificationCenter
職位的方法,以及cacheStage
NSLogs
當前值的制定者。它最終應該等於730,但它永遠不會那麼高。
- (void)setCachingStage:(NSInteger)cachingStage {
_cachingStage = cachingStage;
NSLog(@
"Cache Stage: %d", _cachingStage);
if (_cachingStage == (HZ_NUMBER_OF_TOTAL_YEARS_TO_CACHE*365)) {
self.stateOfCalendarCache = StateOfEventStoreCache_CachingComplete;
NSLog(@"Caching completed.");
}
}
- (void)completeCaching:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] removeObserver:self name:HZ_KVO_CALENDAR_CACHE_NOTIFICATION object:(HZCalendarDay *)notification.object];
self.cachingStage++;
}
這是HZCalendarDay
初始化,即然後獲取事件和提醒的緩存。一旦事件和提醒被設置,它就會Posts
到NotificationCenter
。
- (void)setCacheStage:(NSInteger)cacheStage {
_cacheStage = cacheStage;
if (_cacheStage == 2) {
[[NSNotificationCenter defaultCenter] postNotificationName:HZ_KVO_CALENDAR_CACHE_NOTIFICATION object:self];
}
}
- (id)initOnDate:(NSDate *)date withEventStore:(EKEventStore *)eventStore {
self = [super init];
if (self) {
self.events = [[NSArray alloc] init];
self.reminders = [[NSArray alloc] init];
self.date = date;
self.eventStore = eventStore;
[self fetchAllEvents];
[self fetchAllReminders];
}
return self;
}
- (void)fetchAllEvents {
NSPredicate *fetchPredicateForEvents = [self.eventStore predicateForEventsWithStartDate:[self startTime] endDate:[self endTime] calendars:[self.eventStore calendarsForEntityType:EKEntityTypeEvent]];
self.events = [self.eventStore eventsMatchingPredicate:fetchPredicateForEvents];
// Don't store a nil array in the dictionary.
if (!self.events) {
self.events = [[NSArray alloc] init];
}
self.cacheStage++;
}
- (void)fetchAllReminders {
NSPredicate *fetchPredicateForReminders = [self.eventStore predicateForIncompleteRemindersWithDueDateStarting:[self startTime] ending:[self endTime] calendars:[self.eventStore calendarsForEntityType:EKEntityTypeReminder]];
[self.eventStore fetchRemindersMatchingPredicate:fetchPredicateForReminders completion:^(NSArray *reminders) {
@synchronized (self.reminders) {
self.reminders = reminders;
}
self.cacheStage++;
}];
}
有人可以向我解釋什麼可能會出錯嗎?這與多線程相關嗎?如果是這樣,有沒有更好的方法讓我讓實例化對象的類知道對象已緩存了事件存儲庫提醒?這個類是我的UITableView的數據源,所以我需要緩存提醒,並且讓我的數據源知道緩存已經完成。這允許我的UI在高速緩存發生時在其上顯示「刷新」或加載指示符。
快速注意,如果我更換calendarDay對象作爲一個零參數的通知中心,然後通知中心修建垃圾與成千上萬的NSLog的控制檯。我不確定爲什麼NSNotificationCenter沒有按照預期的方式工作。 –