图像视图未在 NSThread 上更新

Posted

技术标签:

【中文标题】图像视图未在 NSThread 上更新【英文标题】:Image view not updating on NSThread 【发布时间】:2010-11-05 17:47:28 【问题描述】:

我正在尝试制作一个测试应用程序来测量线程的性能。但是,我正在尝试在线程上将图像设置为 imageview 并且它没有更新。事实上,setImage1 和 setImage2 方法甚至都没有被调用。有任何想法吗? 详情看代码

#import "UntitledAppDelegate.h"
#import <QuartzCore/QuartzCore.h>

@implementation UntitledAppDelegate

@synthesize window, imageView1, imageView2, label1, label2, label0;

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
            
    [window makeKeyAndVisible];
    return YES;


-(IBAction) startSeparate:(id) sender

 imageView1.image = imageView2.image = nil;
 double prev;

    start = prev = CACurrentMediaTime(); 
 [self setImage1];
 label1.text = [NSString stringWithFormat:@"%.10g", CACurrentMediaTime() - prev];

 prev = CACurrentMediaTime();  
 [self setImage2];
 label2.text = [NSString stringWithFormat:@"%.10g", CACurrentMediaTime() - prev];


-(IBAction) startThreaded:(id) sender

 imageView1.image = imageView2.image = nil;
 double prev;

 NSThread *t1 = [[NSThread alloc] init];
 [t1 start];
 NSThread *t2 = [[NSThread alloc] init];
 [t2 start];

    start = prev = CACurrentMediaTime(); 
    //This doesn't work
    //[self performSelector:@selector(setImage1) onThread:t1 withObject:nil waitUntilDone:NO];

    //But this does
 [self performSelectorInBackground:@selector(setImage1) withObject:nil];

 label1.text = [NSString stringWithFormat:@"%.10g", CACurrentMediaTime() - prev];

 prev = CACurrentMediaTime();  
 //This doesn't work
    //[self performSelector:@selector(setImage2) onThread:t2 withObject:nil waitUntilDone:NO];

    //But this does
 [self performSelectorInBackground:@selector(setImage2) withObject:nil];

 label2.text = [NSString stringWithFormat:@"%.10g", CACurrentMediaTime() - prev];


-(void) setImage1

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 UIImage *image1 = [UIImage imageNamed:@"bird.png"];
 imageView1.image = image1;
 [self pictureDone];
 [pool drain];


-(void) setImage2

 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 UIImage *image2 = [UIImage imageNamed:@"bird.png"];
 imageView2.image = image2;
 [self pictureDone];
 [pool drain];


-(void) pictureDone

 done++;
 NSLog(@"%i", done);
 if (done == 2) 
  label0.text = [NSString stringWithFormat:@"%.10g", CACurrentMediaTime() - start];
  done = 0;
 

@end

【问题讨论】:

你确定 setImage1 和 setImage2 没有被调用吗?如果你添加一个 NSLog,它会打印吗? 【参考方案1】:

永远不要从后台线程更改当前显示的 UIView 中的任何内容。您可能会遇到一百万种不同的同步问题。在后台线程中下载图片,然后在主线程(从后台线程)调用另一个方法来实际更新 UIImageView

performSelectorOnMainThread:...

至于方法没有运行的问题,试试这个吧:

[self performSelectorInBackground:@selector(setImage2:) withObject:nil];

(在setImage2之后添加一个冒号)。

另外,我认为这两个 NSThread 对象(t1 和 t2)不是必需的,它们也可能造成内存泄漏。

【讨论】:

好吧,但问题是方法 setImage1 和 setImage2 甚至没有被调用 好的,我在帖子中添加了一个可能的解决方案。【参考方案2】:

从技术上讲,NSThread 本身不会自动创建运行循环,那么如果您只是这样创建线程,performSelector:onThread 将无法工作。

【讨论】:

我刚刚发现这实际上是问题所在。我想我得花点时间阅读线程编程指南;) 我不确定你的项目是关于什么的,但在很多情况下使用performSelectorInBackground 就足够了。

以上是关于图像视图未在 NSThread 上更新的主要内容,如果未能解决你的问题,请参考以下文章

UIImageView 图像未在 GCD 的主线程上更新

添加 ViewModel 后,SwiftUI 视图未在按钮切换上更新

UI-NSOperation线程

在我的应用程序中使用简单适配器未在 ListView 上显示图像

UIImage 未在按钮 IBAction 上的 setImage 上更新

在 iOS 上停止 NSThread