#ios #multithreading #nstimer #dispatch
#iOS #многопоточность #nstimer #отправка
Вопрос:
Я искал похожие темы в StackOverflow; есть два похожих сообщения, но я немного тупица и не понимаю приведенные ответы. Моя проблема в том, что когда я запускаю этот код, не указывая, что он должен отправляться в очередь отправки, текущие байты успокаиваются и не продолжают увеличиваться, но когда я указываю, что он должен отправляться в очередь отправки, текущие байты в конечном итоге зашкаливают. Материал, который происходит между
// Здесь много всего
// Завершите много материала здесь
довольно тяжелый, поэтому я бы хотел, чтобы это было не в основном потоке: я хочу, чтобы результаты обеспечивали непрерывное обновление остальной части алгоритма. Кроме того, я получаю иногда странное поведение на графическом дисплее, когда строки отправки закомментированы. Но использование очереди отправки так, как я ее написал, приводит к увеличению количества текущих байтов, в то время как, если я прокомментирую эти строки, количество текущих байтов снизится до постоянного уровня.
Что я делаю не так? Заранее спасибо!
Я запускаю NSTimer в главном потоке:
-(void) startGeoHardware
{
if (self.geoHardwareArrayTimer == nil)
{
self.geoHardwareArrayTimer = [NSTimer scheduledTimerWithTimeInterval:arrayTimerUpdate
target:self
selector:@selector(startGeoHardWareArray:)
userInfo:nil
repeats:YES];
}
}
а затем вызовите метод
- (void) startGeoHardWareArray: (NSTimer *)geoHardwareArrayTimer //: (CMCalibratedMagneticField)field
{
dispatch_queue_t runGeoHardwareArrayQueue = dispatch_queue_create("GeoHardwareArray",NULL);
dispatch_async(runGeoHardwareArrayQueue, ^{
//Do lots of stuff here
//Finish lots of stuff here
});
dispatch_release(runGeoHardwareArrayQueue);
}
geoHardwareArrayTimer определен в файле .h как
NSTimer *geoHardwareArrayTimer;
}
@property(nonatomic,retain) NSTimer *geoHardwareArrayTimer;
и синтезируется в файле .m. и освобождается
if (self.geoHardwareArrayTimer != nil)
{
[self.geoHardwareArrayTimer invalidate];
self.geoHardwareArrayTimer = nil;
}
[super dealloc];
Ответ №1:
Хорошо, это не совсем хороший ответ — он 1) вроде работает и 2) поднимает другой, похожий вопрос — ТЕПЕРЬ, откуда происходит утечка???
При поиске других сообщений я обнаружил метод таймера отправки. Кажется, это работает очень хорошо для того, что я хочу: в этом простом примере я создаю и запускаю два таймера и запускаю методы в отдельных очередях — и, похоже, текущие байты вскоре более или менее успокаиваются до почти постоянной величины. НО в начале есть одноразовая утечка:
OS_dispatch_source libdispatch.dylib _os_object_alloc_realized
для меня это абсолютно ничего не значит.
Есть идеи??? Спасибо
Время
- (void)viewDidLoad
{
[self createDispatchTimers];
}
- (void)createDispatchTimers
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
dispatch_source_t geoHardwareArrayTimer = CreateDispatchTimer(arrayTimerUpdate * NSEC_PER_SEC, (1ull * NSEC_PER_SEC) / arrayTimerLeeway, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Repeating task
[self startGeoHardWareArray:geoHardwareArrayTimer];
});
dispatch_source_t geoHardwareTimer = CreateDispatchTimer(timerUpdate * NSEC_PER_SEC, (1ull * NSEC_PER_SEC) / timerLeeway, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Repeating task
[self runGeoHardware:geoHardwareTimer];
});
}
dispatch_source_t CreateDispatchTimer(uint64_t interval,
uint64_t leeway,
dispatch_queue_t queue,
dispatch_block_t block)
{
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
0, 0, queue);
if (timer)
{
dispatch_source_set_timer(timer, dispatch_walltime(NULL, 0), interval, leeway);
dispatch_source_set_event_handler(timer, block);
dispatch_resume(timer);
}
return timer;
}
void RemoveDispatchSource(dispatch_source_t timer)
{
dispatch_source_cancel(timer);
dispatch_release(timer);
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
///////////////////////////////////////////////////////////////////////////////////////////
///////////////////////// Here are the dispatch queue Methods ///////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////
- (void) startGeoHardWareArray: (dispatch_source_t) geoHardwareArrayTimer
{
dispatch_queue_t runGeoHardwareArrayQueue = dispatch_queue_create("GeoHardwareArray",0);
dispatch_async(runGeoHardwareArrayQueue, ^{
NSLog(@"Array Timer running");
});
dispatch_release(runGeoHardwareArrayQueue);
}
- (void) runGeoHardware: (dispatch_source_t) geoHardwareTimer
{
dispatch_queue_t runGeoHardwareQueue = dispatch_queue_create("GeoHardware",0);
dispatch_async(runGeoHardwareQueue, ^{
NSLog(@"Hardware Timer running");
});
dispatch_release(runGeoHardwareQueue);
}