我dispatch queues
同时运行两个不同的对象,循环 365 次迭代并实例化一个对象。该循环将对象添加到NSNotificationCenter
,然后对象在其事件存储异步代码块完成后发布通知。我遇到的问题是我应该在调试器中收到 730 条消息,但我没有。每次运行应用程序时,我都会收到不同数量的消息,从 513 到 630。
发生这种情况有什么原因吗?
这是我执行循环并将对象添加到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 在缓存发生时在其上显示“刷新”或加载指示器。