可可图像库窗口

时间:2011-03-24 17:24:10

标签: objective-c cocoa xcode macos nsimageview

我在应用程序中有一个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()并进行了调试,我确信枚举工作正常,因为我可以看到新的图像信息正确设置。

我有什么遗漏或者这是解决这个问题的完全错误的方法吗?

谢谢,

克雷格

1 个答案:

答案 0 :(得分: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];