Что мне нужно сделать: чтобы избежать глобальной переменной, у меня есть класс Singleton, содержащий массив. К этому массиву будут обращаться два разных потока:
- 1) первый будет основным потоком и ему придется время от времени добавлять объекты в этот NSMutableArray.
- 2) другой поток зацикливается (в то время как TRUE) и попытаться очистить массив (если он что-то содержит)
Моя идея была (и что я сделал до сих пор): в моем одноэлементном классе у меня есть NSMutableArray (list
) и NSCondition (conditionLock
).
Что делает мой основной поток:
[[sharedSingleton conditionLock] lock];
[[sharedSingleton list] addObject:obj];
[[sharedSingleton conditionLock] signal];
[[sharedSingleton conditionLock] unlock];
Я хочу заблокировать объект, чтобы он не опустел, когда я пытаюсь поместить в него объекты. (защита общей памяти). Как только объект помещен в массив, я сигнализирую другому потоку. Если я правильно понял, это своего рода увеличение счетчика, как с семафором, верно? Сигнал сообщает другому потоку: «Есть объект, продолжайте».
Что делает второй поток:
while (YES) {
[[sharedRequest conditionLock] lock];
[[sharedRequest conditionLock] wait];
RequestLauncher * req = [[RequestLauncher alloc] initWithGenericsObject:[[sharedRequest list] objectAtIndex:0]];
[req performSelectorOnMainThread:@selector(Launch)
withObject: nil
waitUntilDone:YES];
[[sharedRequest list] removeObjectAtIndex:0];
[[sharedRequest conditionLock] unlock];
}
Итак, я думаю, моя проблема в том, что я блокирую, а затем жду сигнала, но все примеры Apple находятся в таком порядке. Этот код работает, когда я добавляю один объект в свой основной поток. Однако, когда я хочу добавить более одного, он блокируется вокруг замка.
EDIT Я пробовал что-то другое, но поведение было не таким, как ожидалось:
Таким образом, я разблокировал NSMutableArray, чтобы mainThread мог добавлять объекты.
while (YES) {
[[sharedRequest conditionLock] lock];
[[sharedRequest conditionLock] wait];
GenericsObject * obj = [[sharedRequest list] objectAtIndex:0];
[[sharedRequest list] removeObjectAtIndex:0];
[[sharedRequest conditionLock] unlock];
RequestLauncher * req = [[RequestLauncher alloc] initWithGenericsObject:obj];
[req performSelectorOnMainThread:@selector(Launch) withObject: nil waitUntilDone:YES];
}