Как использовать нативные типы C с executeSelectorOnMainThread :? - PullRequest
3 голосов
/ 16 сентября 2009

Я бы хотел позвонить (void)setDoubleValue:(double)value, используя performSelectorOnMainThread:.

Я думал, что это сработает:

NSNumber *progress = [NSNumber numberWithDouble:50.0];
[progressIndicator performSelectorOnMainThread:@selector(setDoubleValue:)
                                    withObject:progress
                                 waitUntilDone:NO];

Не работает.

Затем я реализовал вспомогательный метод:

- (void)updateProgressIndicator:(NSNumber *)progress
{
    [progressIndicator setDoubleValue:[progress doubleValue]];
}

Работает, но не совсем чисто.

После этого я попробовал это с NSInvocation.

NSInvocation *setDoubleInvocation;;
SEL selector = @selector(setDoubleValue:);
NSMethodSignature *signature;
signature = [progressIndicator methodSignatureForSelector:selector];
setDoubleInvocation = [NSInvocation invocationWithMethodSignature:signature];
[setDoubleInvocation setSelector:selector];
[setDoubleInvocation setTarget:progressIndicator];

double progress = 50.0;
[setDoubleInvocation setArgument:&progress atIndex:2];

[setDoubleInvocation performSelectorOnMainThread:@selector(invoke)
                                      withObject:nil
                                   waitUntilDone:NO];

Это решение работает, но использует много кода и работает довольно медленно. (Даже если я сохраню вызов.)

Есть ли другой способ?

Ответы [ 4 ]

9 голосов
/ 16 сентября 2009

Если вы находитесь на Snow Leopard, вы можете использовать блоки:

dispatch_async(dispatch_get_main_queue(), ^{
    [progressIndicator setDoubleValue: 50.0];
});
7 голосов
/ 16 сентября 2009

вам нужно написать собственный метод распаковки для переноса setDoubleValue :. - (void) setDoubleValueAsNumber: (NSNumber *) number { [self setDoubleValue: [number doubleValue]]; }

2 голосов
/ 18 сентября 2009

Дейв Дрибин имеет решение для этого , которое принимает форму категории на NSObject. Его категория оборачивает вызов метода в NSInvocation и вызывает его в основном потоке. Таким образом, вы можете использовать любой интерфейс метода, который вам нравится, включая примитивные типы для ваших аргументов.

Фреймворк Amber также имеет категорию для NSObject, которая добавляет прокси основного потока, где любые сообщения, отправленные этому прокси, выполняются в основном потоке.

0 голосов
/ 26 марта 2011

Это сообщение в блоге: http://www.cimgf.com/2008/03/01/does-objective-c-perform-autoboxing-on-primitives/ указывает на то, что, хотя Cocoa не будет автоматически примитивировать примитивы, он автоматически их распакует. Таким образом, числа и BOOL по крайней мере могут быть переданы как класс NSNumber, и вызываемая функция автоматически распакует его. Я играл с использованием прокси-объекта (Uli's UKMainThreadProxy *), который работает довольно хорошо, хотя я уверен, что он имеет свои ограничения, как и все остальное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...