Я немного растерялся из-за использования этих двух.
У меня есть фоновый поток, который выполняет тяжелую загрузку данных и применяет их к Базовой базе данных на устройстве iOS.
Код в фоновом потоке вызывает класс общего экземпляра ProgressController для обновления прогресса в пользовательском интерфейсе (который, как я знаю, выполняется в основном потоке). Затем ProgressController имеет делегата, который назначается View Controller сверху.
Все работает нормально, за исключением того, что пользовательский интерфейс не обновляется после запуска фонового потока. Я знаю, что делегат вызывается, потому что я запускаю NSLogs с текстом, который передается.
Теперь я прочитал, что должен использовать executeSelectorOnMainThread, но это кажется излишним, учитывая, что делегат увольняется.
Должен ли я вместо этого использовать executeSelectorOnMainThread и вообще не использовать делегатов.
Я что-то упустил?
Если бы кто-то мог объяснить, я был бы очень благодарен.
Спасибо
Крис.
В фоновом потоке
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
#import "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
в контроллере вида
- (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;
}