2011-05-01 71 views
0

我有一个资产管理器,需要通知所有者它的资产已准备就绪。我向消费者发送令牌以听取倾听通知以避免更紧密的耦合。问题是当资产已经加载时,我需要在延迟后调用loadComplete。在objective-c中执行此操作的最佳方法是什么?模拟异步函数调用

资产管理

-(tokenString*) loadAssetPath:(NSString*) asset { 
    //start asynchronous load 
    //or if assets ready send complete  <-- issue 
    return nonceToken; 
} 
-(void)loadComplete { 
    [[NSNotificationCenter defaultCenter] 
     postNotificationName:tokenString object:self]; 
} 

消费者

NSString* token; 
-(void) loadSomething { 
    if(token) 
     [self removeListener]; 
    token = [[AssetManager sharedManager] 
     loadAssetPath:@"http://server.dev/myLargeImage.png"]; 
    [[NSNotificationCenter defaultCenter] 
     addObserver:[AssetManager sharedManager] 
     selector:@selector(assetLoaded:) name:token]; 
} 
-(void)assetLoader:(NSNotifcation*)aNotification { 
    [self removeListener]; 
    //continue on with stuffing stuff 
} 
+0

我刚刚发现'performSelector:withObject:afterDelay:'看起来应该可以工作。如果我调用'[self performSelector:@selector(loadingMethod :) withObject:asset afterDelay:0.3];'并且在资产已经下载时直接调用loadMethod loadComplete:tokenString。这看起来应该起作用。 – puppybits 2011-05-01 16:09:09

+0

0.3没有必要。除非需要特定的时间(例如计时器),否则通常应该在这里传递0。 – 2011-05-01 16:20:53

回答

1

使用的NSObject的performSelector功能,这使得它的延迟后调用。

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay 

你甚至可以使用这个函数的形式到另一个线程,这是在做冗长的操作时,不会阻塞主线程有用运行(只是不与此线程的UI对象淤泥) 。

0

@DavidNeiss对于performSelector:withObject:afterDelay:是正确的,但你几乎肯定不想在这里实际发生时间延迟。最多你想在下一个事件循环中执行你的选择器,这样对于监听器来说是一致的。所以你应该延迟0.这与正常的performSelect:withObject:不同,它会立即执行选择器同步。

-(tokenString*) loadAssetPath:(NSString*) asset { 
    //start asynchronous load 
    if (<load is actually complete>) { 
     // -loadComplete will execute on the next event loop 
     [self performSelector:@selector(loadComplete) withObject:nil afterDelay:0]; 
    } 

    return nonceToken; 
}