iphone - 委托(delegate)和执行SelectorOnMainThread

标签 iphone multithreading uiview delegates nsnotifications

我对这两个的使用有点困惑。

我有一个后台线程,它负责下载数据并将其应用到 iOS 设备内的核心数据数据库。

后台线程中的代码调用共享实例类 ProgressController 来更新 UI 上的进度(我知道它在主线程中运行)。然后,ProgressController 有一个委托(delegate),该委托(delegate)由顶部的 View Controller 分配。

一切工作正常,只是后台线程启动后 UI 不会更新。我知道委托(delegate)正在被调用,因为我已经使用正在传递的文本触发了 NSLogs。

现在我读到我应该使用performSelectorOnMainThread,但是考虑到委托(delegate)正在触发,这似乎是多余的。

我应该使用performSelectorOnMainThread 来代替而不使用委托(delegate)吗?

我错过了什么吗?

如果有人能解释一下,我将不胜感激。

谢谢

克里斯。

在后台线程内

progressController = [ProgressController sharedInstance];
[progressController open];

...

[progressController updateProgress:NSLocalizedString(@"Update text here", @"Update text here")];

ProgressController.h 内

#import <Foundation/Foundation.h>

@protocol ProgressControllerDelegate 
@required
- (void) displayProgress:(NSString *)text;
- (void) showProgress;
- (void) hideProgress;

@end

@interface  ProgressController : NSObject {

    NSString    *currentProgress;
    BOOL        progressOnDisplay;
    id          delegate;
}

+ (ProgressController *)sharedInstance;

@property (nonatomic) BOOL  progressOnDisplay;
@property (nonatomic, assign) id delegate;

-(void) open;
-(void) updateProgress:(NSString *)text;
-(void) reDisplayProgress;
-(void) close;

@end

ProgressController.m 内 #导入“ProgressController.h”

@implementation ProgressController

@synthesize progressOnDisplay;
@synthesize delegate;

static ProgressController *sharedInstance;

+ (ProgressController *)sharedInstance {
    @synchronized(self) {
        if (!sharedInstance)
        [[ProgressController alloc] init];              
    }
    return sharedInstance;
}

+(id)alloc {
    @synchronized(self) {
        NSAssert(sharedInstance == nil, NSLocalizedString(@"Attempted to allocate a second instance of a singleton ProgressController.", @"Attempted to allocate a second instance of a singleton ProgressController."));
        sharedInstance = [super alloc];
    }
    return sharedInstance;
}
-(id) init {
    if (self = [super init]) {
        [self open];
    }
    return self;
}

// Ask delegate to show new Progress Label
-(void) open {
    progressOnDisplay = TRUE;
    currentProgress = @"";
    [self.delegate showProgress];
}

// Ask delegate to update and display Progress text
-(void) updateProgress:(NSString *)text {
    currentProgress = text;
    [self.delegate displayProgress:currentProgress];

}

// Ask delegate display existing Progress text if any
-(void) reDisplayProgress {
    if (currentProgress != @"") {
        [self.delegate displayProgress:currentProgress];
        [self.delegate showProgress];   
    }
}

// Ask delegate to clear and hide Progress Label
-(void) close {
    progressOnDisplay = FALSE;
    currentProgress = @"";
    [self.delegate hideProgress];
}


@end

在 View Controller 内

- (void)viewDidLoad {
    [super viewDidLoad];

    progressController = [ProgressController sharedInstance];
    progressController.delegate = self;
    [progressController reDisplayProgress]; // In case progress has been updated prior to the view load

}

// Delegate method to show Progress Label
- (void) showProgress {
    progressView.hidden = FALSE;    

}

// Delegate method to display specific text in Progress label
- (void) displayProgress:(NSString *)text {
    [progressLabel setText:text];
    [progressView setNeedsDisplay];

    DLog(@"Reporting -  %s", [text UTF8String]);  // I can see that this is firing successfully

}

// Delegate method to hide Progress Label
- (void) hideProgress {
    progressView.hidden = TRUE;

}

最佳答案

您插入的代码显示您直接从后台线程调用委托(delegate)方法。要在主线程上执行 GUI 工作(您应该这样做),您需要在调用委托(delegate)方法时直接使用 performSelectorOnMainThread: 或在委托(delegate)方法本身中使用。如果您想在这些更新期间停止后台线程,您可以使用 waitUntilDone:YES 的变体。

关于iphone - 委托(delegate)和执行SelectorOnMainThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5702179/

相关文章:

multithreading - Delphi和线程: “System Error. Code: 1400. Invalid window handle”

java - 无法重启线程

ios - Swift - 呈现一个 UIView(不是 ViewController)

ios - 如何通过 IBAction 从带有动画的 tableView 中删除单元格? iOS swift 3.0

iphone - 如何在 iOS 上的应用程序之间共享值

ios - 转到新的 UIViewController 时如何从层次结构中删除 UIViewController?

iphone - 使用 phonegap 进行连续图像捕获

c - 快速解决死锁?

iphone - 如何制作不规则形状 uiview 并将 uiimageview 放入这些形状中,例如 instacollage iphone 应用程序

ios - Apple App 因 IPV6 崩溃而被拒绝