NSThread читает ивары родителей?

Я отсоединяю новый NSThread withObject:self, чтобы поток мог вызывать основной поток в качестве делегата. Однако мне также нужно, чтобы новый поток мог читать некоторые значения в родительском потоке. С NSThread я могу передать только один объект withObject, и я использую его для передачи себя из-за методов делегата. Есть ли способ, которым мой новый поток может считывать значения из своего родителя? Возможно, через переданный ему объект self?

Вот где я запускаю тему:

MulticastDaemon* multicastDaemon = [[MulticastDaemon alloc] init];
[NSThread detachNewThreadSelector:@selector(doWorkWithDelegate:)
                         toTarget:multicastDaemon
                       withObject:self];

Я хочу передать многоадресный IP-адрес и номер порта демону, чтобы он знал, что слушать, но я не уверен, как передать эти значения в multicastDaemon.

Как multicastDaemon может получить доступ к этим значениям?


person Adam    schedule 15.11.2011    source источник


Ответы (3)


Вы можете немного изменить интерфейс своего MulticastDaemon, чтобы установить делегата перед созданием нового потока. Затем вы освобождаете слот withObject:, чтобы передать что-то еще. Это позволяет избежать доступа к переменным между потоками.

Либо:

 MulticastDaemon* multicastDaemon = [[MulticastDaemon alloc] initWithDelegate:self];
[NSThread detachNewThreadSelector:@selector(doWorkWithInformation:)
                         toTarget:multicastDaemon
                       withObject:operatingInfo];

Or

MulticastDaemon* multicastDaemon = [[MulticastDaemon alloc] init];
[multicastDaemon setDelegate:self];

В противном случае вам придется создать метод, который демон может вызывать для своего делегата, который собирает и упаковывает информацию для передачи обратно. В этом случае вам, вероятно, придется начать беспокоиться о безопасности потоков.

person jscs    schedule 15.11.2011
comment
Потокобезопасность — новая концепция для меня. Мне нужно будет немного почитать. В итоге я сделал что-то вроде: port = [delegate portNumber]; Поскольку self был делегатом, поток имеет легкий доступ, верно? - person Adam; 16.11.2011
comment
да. Проблема безопасности потоков заключается в том, что значение может измениться во время доступа к нему, что приведет к получению недопустимого результата. Если нет возможности изменить номер порта после запуска демона, вам не о чем беспокоиться. - person jscs; 16.11.2011
comment
Я немного почитал и согласен с вашим комментарием. В моем случае, я не думаю, что мне нужно беспокоиться. Я читаю значения порта/адреса в новые значения, а затем порт/адрес можно изменить. Если это так, поток отменяется и запускается другой поток с новыми значениями. Я не вижу ни одного случая, когда значения могли бы быть записаны во время их чтения. - person Adam; 17.11.2011
comment
Это будет безопасно, только если вы говорите о примитивах (ints/floats/structs и т. д.). Если номер порта и другие значения являются объектами, их необходимо copy . В противном случае вы все еще используете тот же кусок памяти. - person jscs; 17.11.2011

Да, вы можете получить доступ к переменным, сделав их свойствами, а затем выполнив что-то вроде этого (вы не говорите, из какого класса сделан этот вызов, поэтому я назвал его MyClass):

@implementation MulticastDaemon

-(void) doWorkWithDelegate:(MyClass*) cls
{
    cls.value1 = 12;
    ...
}

...

@end

РЕДАКТИРОВАТЬ: исправлена ​​реализация.

person trojanfoe    schedule 15.11.2011

Вам лучше использовать подкласс NSOperation, а затем добавить его в NSOperationQueue. Вы можете добавить любые дополнительные параметры к этому подклассу операций.

Есть еще одно преимущество NSOperation перед NSThread. NSOperation и NSOperationQueue построены поверх GCD, и многопоточность гораздо более оптимальна, чем NSThread.

Но вы также можете просто добавить некоторые свойства вашему MulticastDaemon.

person Max    schedule 15.11.2011