Frage

Ich habe eine NSOperation. Wenn es fertig ich Feuer ist das Programm Know ein NSNotificationCenter zu lassen, dass die NSOperation beendet ist und die GUI zu aktualisieren.

Zu meinem Verständnis Zuhörer auf die NSNotification wird auf dem Haupt-Thread nicht ausgeführt werden, weil die NSOperation nicht auf dem Haupt-Thread ist.

Wie kann ich es so, dass die Zuhörer auf dem Haupt-Thread ausgeführt werden, wenn ich mein Ereignis ausgelöst?

[[NSNotificationCenter defaultCenter] postNotificationName:@"myEventName" object:self]; 
War es hilfreich?

Lösung

Sie können mit performSelectorOnMainThread:withObject:waitUntilDone: mit einer Hilfsmethode, in ähnlicher Weise wie im folgende Beispiel mit

.....
[self performSelectorOnMainThread:@selector(fireNotification) withObject:nil waitUntilDone:YES];
...

- (void)fireNotification {
  [[NSNotificationCenter defaultCenter] postNotificationName:@"myEventName" object:self]; 
}

Wenn Sie nicht warten, bis getan, müssen Sie die Fälle prüfen, wo andere Threads auf das Objekt beziehen, die bereits vor dem Haupt-Thread gereinigt werden konnten wird aufgerufen.

Andere Tipps

Update: Dispatch-Warteschlangen machen sehr einfach eine Benachrichtigung auf dem Haupt-Thread posten.

dispatch_async(dispatch_get_main_queue(),^{
   [[NSNotificationCenter defaultCenter] postNotification...];
});

Um die Meldung Handler bis zum Ende warten, nur ersetzen dispatch_async mit dispatch_sync.


notnoop Antwort Folgen, hier einige Infrastruktur, die Sie sicher nutzen können Ihre Benachrichtigungen auf dem Haupt-Thread posten ohne für sie bis zum Ende warten. Hoffentlich wird jemand diese Informationen hilfreich finde

NSNotificationCenter + Utils.h:

@interface NSNotificationCenter (Utils)

-(void)postNotificationOnMainThread:(NSNotification *)notification;
-(void)postNotificationNameOnMainThread:(NSString *)aName object:(id)anObject;
-(void)postNotificationNameOnMainThread:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

@end

NSNotificationCenter + Utils.m:

@interface NSNotificationCenter (Utils_Impl) {
}

-(void)postNotificationOnMainThreadImpl:(NSNotification*)notification;
-(void)postNotificationNameOnMainThreadImpl:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo;

@end

@implementation NSNotificationCenter (Utils)

-(void)postNotificationOnMainThread:(NSNotification *)notification {
    [notification retain];
    [notification.object retain];
    [self performSelectorOnMainThread:@selector(postNotificationOnMainThreadImpl:) 
                           withObject:notification
                        waitUntilDone:NO];
}

-(void)postNotificationNameOnMainThread:(NSString *)aName object:(id)anObject {
    [self postNotificationNameOnMainThread:aName object:anObject userInfo:nil];
}

-(void)postNotificationNameOnMainThread:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo {
    [aName retain];
    [anObject retain];
    [aUserInfo retain];

    SEL sel = @selector(postNotificationNameOnMainThreadImpl:object:userInfo:);
    NSMethodSignature* sig = [self methodSignatureForSelector:sel];
    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig];
    [invocation setTarget:self];
    [invocation setSelector:sel];
    [invocation setArgument:&aName atIndex:2];
    [invocation setArgument:&anObject atIndex:3];
    [invocation setArgument:&aUserInfo atIndex:4];
    [invocation invokeOnMainThreadWaitUntilDone:NO];
}

@end

@implementation NSNotificationCenter (Utils_Impl)

-(void)postNotificationOnMainThreadImpl:(NSNotification*)notification {
    [self postNotification:notification];
    [notification.object release];
    [notification release];
}

-(void)postNotificationNameOnMainThreadImpl:(NSString *)aName object:(id)anObject userInfo:(NSDictionary *)aUserInfo {
    [self postNotificationName:aName object:anObject userInfo:aUserInfo];
    [aName release];
    [anObject release];
    [aUserInfo release];
}

@end

NSInvocation + Utils.h:

@interface NSInvocation (Utils)

-(void)invokeOnMainThreadWaitUntilDone:(BOOL)wait;

@end

NSInvocation + Utils.m:

@implementation NSInvocation (Utils)

-(void)invokeOnMainThreadWaitUntilDone:(BOOL)wait
{
    [self performSelectorOnMainThread:@selector(invoke)
                           withObject:nil
                        waitUntilDone:wait];
}

@end

Wenn Sie auf 10.6 sind, können Sie auch ein href verwenden <= "http://developer.apple.com/mac/library/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref / doc / uid / TP40004591-RH2-SW36" rel = "noreferrer"> setCompletionBlock: . Es wird wie folgt verwendet:

NSOperation*op= .... ;
[op setCompletionBlock:^{
    dispatch_async(dispatch_get_main_queue(),^{
        code to be run on the main thread after the operation is finished.
    });
}];

Für allgemeine Einführung in den Blöcken und GCD, dieser Artikel sehr hilfreich war. Ich fand GCD & setCompletionBlock einfacher als NSNotification zu lesen. Ein Nachteil ist, na ja, es läuft nur auf 10,6!

Um auf Antwort Danra des erweitern hier die ARC-kompatible Version der Kategorie I zusammengestellt:

NSNotificationCenter + Threads.h

@interface NSNotificationCenter (Threads)

-(void)postNotificationOnMainThread:(NSNotification *)notification;
-(void)postNotificationNameOnMainThread:(NSString *)name object:(id)object;
-(void)postNotificationNameOnMainThread:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo;

@end

NSNotificationCenter + Threads.m

@implementation NSNotificationCenter (Threads)

-(void)postNotificationOnMainThread:(NSNotification *)notification
{
    [self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];
}

-(void)postNotificationNameOnMainThread:(NSString *)name object:(id)object
{
    [self postNotificationNameOnMainThread:name object:object userInfo:nil];
}

-(void)postNotificationNameOnMainThread:(NSString *)name object:(id)object userInfo:(NSDictionary *)userInfo
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self postNotificationName:name object:object userInfo:userInfo];
    });
}

@end
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top