0

我在应用程序中有一个 HUD 面板,我希望能够拍摄一组图像并在面板上显示每个图像几秒钟,然后再显示下一个图像。我对 Cocoa 很陌生,并且在实现这一点时遇到了麻烦,所以欢迎一些指针。这是我目前正在尝试的:

[newShots enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop) 
 {
     //get url
     NSURL *imageUrl = [[NSURL alloc] initWithString:[obj objectForKey:@"image_url"]];;

     //get image from url
     NSImage *image = [[NSImage alloc] initWithContentsOfURL:imageUrl];

     //set it to shot panel
     [shotPanelImageView setImage:image]; 

     //clean up
     [imageUrl release];
     [image release];

     //set needs refresh
     [shotPanelImageView setNeedsDisplay:YES];

     //sleep a few before moving to next
     [NSThread sleepForTimeInterval:3.0];
 }]; 

如您所见,我只是在循环每个图像的信息,通过 URL 获取它,将其设置为视图,然后在继续之前调用线程睡眠几秒钟。问题是视图在分配时不会用新图像重绘。我认为 setNeedsDisplay:YES 会强制重绘,但只会显示集合中的第一张图像。我已经放入 NSLog() 并进行了调试,并且我确信枚举工作正常,因为我可以看到新的图像信息正在按应有的方式设置。

是否有我遗漏的东西,或者这是解决这个问题的完全错误的方法?

谢谢,

克雷格

4

1 回答 1

1

您正在休眠主线程,我很确定这不是一个好主意。我建议 Cocoa 做你想做的事是使用计时器。代替上面的代码:

[NSTimer scheduledTimerWithTimeInterval:3.0
                                 target:self
                               selector:@selector(showNextShot:)
                               userInfo:nil
                                repeats:YES];

(该userInfo参数允许您在计时器触发时传递要使用的任意对象,因此您可以使用它来跟踪当前索引作为 NSNumber,但它必须包装在可变容器对象中, 因为以后不能设置。)

然后将代码块中的代码放入计时器调用的方法中。您需要为当前索引创建一个实例变量。

- (void)showNextShot:(NSTimer *)timer {
    if( currentShotIdx >= [newShots count] ){
        [timer invalidate]; // Stop the timer
        return;    // Also call another cleanup method if needed
    }
    NSDictionary * obj = [newShots objectAtIndex:currentShotIdx];
    // Your code...
    currentShotIdx++;
}

为了避免使用计时器导致的初始 3 秒延迟,您可以在设置之前调用您的计时器使用的相同方法:

[self showNextShot:nil]
[NSTimer scheduled...

或者也可以安排一个非重复计时器尽快触发(如果你真的想使用userInfo):

[NSTimer scheduledTimerWithTimeInterval:0.0
                                      ...
                                repeats:NO];

编辑:我忘了-initWithFireDate:interval:target:selector:userInfo:repeats:

NSTimer *tim = [[NSTimer alloc] initWithFireDate:[NSDate date]
                                        interval:3.0
                                          target:self
                                        selector:@selector(showNextShot:)
                                        userInfo:nil
                                         repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:tim 
                             forMode:NSDefaultRunLoopMode];
[tim release];
于 2011-03-24T20:12:25.707 回答