Я пытаюсь отследить проблему с зависанием в приложении, которое я разрабатываю.Я могу быть в глубоком конце NSAutoreleasePool и напортачить.
Приложение воспроизводит MIDI-файл.Если я закомментирую приведенный ниже код "simRespondToFileNote" , который использует NSAutoreleasePool, он не зависнет.Если я разрешу запускать код, он будет зависать в кажущихся случайными точках. Выход из журнала сбоев / консоли, похоже, не указывает, где возникает проблема.
Вот поток программы:
Я использую Bass midi lib (C lib);он воспроизводит MIDI-файл в своем собственном потоке.
Когда происходит событие midi, запускается обратный вызов, и я оборачиваю данные события midi в NSDictionary и направляем их в основной поток, чтобы я мог выполнять обновления пользовательского интерфейса и некоторые другие вещи.
Вот код, который выполняет маршрутизацию:
- (void)forwardFileNoteIn:(int) note withVelocity: (int) velocity
{
int position = BASS_ChannelGetPosition(midiFileStream, BASS_POS_MIDI_TICK);
float percent = ((float)position / (float)totalTicks);
int ticksInLoop = outLoopTick - inLoopTick;
QWORD bytes=BASS_ChannelGetPosition(midiFileStream, BASS_POS_BYTE); // get position in bytes
double seconds=BASS_ChannelBytes2Seconds(midiFileStream, bytes); // translate to seconds
int timeStamp =seconds*1000; // translate to milliseconds
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSDictionary *midiData = [NSDictionary dictionaryWithObjectsAndKeys:
@"fileNoteIn", @"eventType",
[NSNumber numberWithInt:note], @"note",
[NSNumber numberWithInt:velocity],@"velocity",
[NSNumber numberWithInt:timeStamp],@"timeStamp",
[NSNumber numberWithInt:position],@"position",
[NSNumber numberWithFloat:percent],@"percentPlayed",
[NSNumber numberWithInt:ticksInLoop],@"ticksInLoop",
nil];
[delegate performSelectorOnMainThread:@selector(midiFileEvent:)
withObject:midiData
waitUntilDone:NO];
[pool release];
}
- От делегата сообщение отправляется другому объектуиспользуя экземпляр NSDictionary в качестве параметра.Этот объект либо отправляет экземпляр NSDictionary немедленно другому объекту, либо ставит его в очередь для отправки после небольшой задержки (используя executeSelector: afterDelay: ).
Возможно ли эточто NSAutoreleasePool удаляет экземпляр NSDictionary до запуска сообщения в очереди?Я нигде не сливаю бассейн - я должен это делать?
- (void)simRespondToFileNote:(NSDictionary *)dictionary
{
int velocity = [[dictionary objectForKey:@"velocity"] intValue];
if (velocity == 0){
// noteOff - send it through
[delegate routeUserSimMidiEvent:dictionary];
} else {
float totalPercentCorrect = [dataSource getUserCorrectPercent];
int note = [[dictionary objectForKey:@"note"] intValue];
if (totalPercentCorrect < _userAccuracy){
float lateNoteOnTimeDelay = (dataSource.postTimeHighAccuracy - (dataSource.postTimeHighAccuracy /4)) / 1000.;
float lateNoteOffTimeDelay = lateNoteOnTimeDelay + .1; // revise
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// create noteOff data w/ velocity == 0; timeStamp == 0;
NSDictionary *midiData = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:note], @"note",
[NSNumber numberWithInt:0],@"velocity",
[NSNumber numberWithUnsignedInt:0],@"timeStamp",
nil];
[self performSelector:@selector(simLateResponseToFileNote:) withObject:dictionary afterDelay: lateNoteOnTimeDelay];
[self performSelector:@selector(simLateResponseToFileNote:) withObject:midiData afterDelay: lateNoteOffTimeDelay];
[pool release];
} else {
float lateNoteOnTimeDelay = (dataSource.postTimeLowAccuracy + (dataSource.postTimeLowAccuracy /4)) / 1000.0;
float lateNoteOffTimeDelay = lateNoteOnTimeDelay + .1; // revise
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// create noteOff data w/ velocity == 0; timeStamp == 0;
NSDictionary *midiData =[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:note], @"note",
[NSNumber numberWithInt:0],@"velocity",
nil];
// queue late noteOn
[self performSelector:@selector(simLateResponseToFileNote:) withObject:dictionary afterDelay: lateNoteOnTimeDelay];
// queue late noteOff
[self performSelector:@selector(simLateResponseToFileNote:) withObject:midiData afterDelay: lateNoteOffTimeDelay];
[pool release];
}
}
}