Изменить:
Спасибо @BlackFrog. Я думаю, что я уже ближе, но значения все еще не доходят...
Значения устанавливаются, как показано в журналах в [progressController updateProgressSummary:...], но равны нулю, когда я регистрирую их в progressUpdate initWithProgressUpdate:.... как показано ниже.
Я немного запутался в том, какое свойство используется: один набор для progressUpdate или те, которые установлены для каждого из трех компонентов progressUpdate. Я изменил 3 отдельных свойства с назначения на сохранение, как было предложено, а также попытался сделать то же самое с общим свойством progressUpdate (здесь не показано).
ProgressController.h
......
@property (nonatomic, assign) ProgressUpdate *progressUpdate;
progressController.m
// Ask delegate to update and display Progress text
-(void) updateProgressSummary:(NSString *)summary detail:(NSString *)detail percentComplete:(NSNumber *)complete {
// These report the proper values
DLog(@"Reporting Summary - %s", [summary UTF8String]);
DLog(@"Reporting Detail - %s", [detail UTF8String]);
DLog(@"Reporting Complete - %i", [complete intValue]);
if (summary != nil)
self.progressUpdate.summaryText = summary;
self.progressUpdate.detailText = detail;
self.progressUpdate.percentComplete = complete;
ProgressUpdate *progressUpdateForIssue = [[ProgressUpdate alloc] initWithProgressUpdate:progressUpdate];
[self.delegate performSelectorOnMainThread:@selector(displayProgress:) withObject:progressUpdateForIssue waitUntilDone:NO];
[progressUpdateForIssue release];
}
Но через несколько миллисекунд... внутри объекта... они равны нулю.
progressUpdate.h
.....
@property (nonatomic, retain) NSString *summaryText;
@property (nonatomic, retain) NSString *detailText;
@property (nonatomic, retain) NSNumber *percentComplete;
progressUpdate.m
-(id) initWithProgressUpdate:(ProgressUpdate *)update {
if ((self = [super init])) {
summaryText = [update.summaryText copy];
detailText = [update.detailText copy];
percentComplete = [[NSNumber alloc] initWithFloat:[update.percentComplete floatValue]];
}
// These report nil values
DLog(@"Reporting in progUpdate summaryText - %s", [summaryText UTF8String]);
DLog(@"Reporting in progUpdate detailText - %s", [detailText UTF8String]);
DLog(@"Reporting in progUpdate percentComplete - %i", [percentComplete intValue]);
return self;
}
конец обновления
Мне нужна помощь с передачей данных в пользовательском классе из одного потока в другой. Он есть перед проходом, но затем исчезает по прибытии. Я перепробовал все, что знал, но безрезультатно.
Мой фоновый поток вызывает ProgressController и передает ему сведения о текущем прогрессе. Это, в свою очередь, выполняет действие SelectorOnMainThread для делегата ProgressController (контроллера представления) для отображения деталей.
Все работало нормально, когда я проходил через одну NSString, но мне нужно передать две строки и число, а так как PerformSelectorOnMainThread может передать только один объект, я инкапсулировал их в пользовательский объект — ProgressUpdate.
Данные проходят через ProgressController правильно, но к тому времени, когда они появляются в контроллере представления, становятся нулевыми. Я знаю это, так как размещал NSLogs в разных местах.
Интересно, связано ли это с:
многопоточность и пользовательские объекты
тот факт, что ProgressController является синглтоном, поэтому я выделял новый ProgressUpdate каждый раз, когда он вызывается, но это не помогло.
Любые идеи приветствуются. Для ясности код ниже.
ProgressUpdate.h
#import <Foundation/Foundation.h>
@interface ProgressUpdate : NSObject {
NSString *summaryText;
NSString *detailText;
NSNumber *percentComplete;
}
@property (nonatomic, assign) NSString *summaryText;
@property (nonatomic, assign) NSString *detailText;
@property (nonatomic, assign) NSNumber *percentComplete;
-(id) initWith:(ProgressUpdate *)update;
@end
ProgressUpdate.m
#import "ProgressUpdate.h"
@implementation ProgressUpdate
@synthesize summaryText, detailText, percentComplete;
-(id) initWith:(ProgressUpdate *)update {
self = [super init];
self.summaryText = update.summaryText;
self.detailText = update.detailText;
self.percentComplete = update.percentComplete;
return self;
}
@end
ProgressController.m
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 update and display Progress text
-(void) updateProgressSummary:(NSString *)summary detail:(NSString *)detail percentComplete:(NSNumber *)complete {
if (summary != nil)
self.progressUpdate.summaryText = summary;
self.progressUpdate.detailText = detail;
self.progressUpdate.percentComplete = complete;
ProgressUpdate *progressUpdateForIssue = [[ProgressUpdate alloc] initWith:progressUpdate];
[self.delegate performSelectorOnMainThread:@selector(displayProgress:) withObject:progressUpdateForIssue waitUntilDone:NO];
[progressUpdateForIssue release];
}
RootViewController.m
// Delegate method to display specific text in Progress label
- (void) displayProgress:(ProgressUpdate *)update {
[progressSummaryLabel setText:update.summaryText];
[progressDetailLabel setText:update.detailText];
[progressBar setProgress:[update.percentComplete intValue]];
[progressView setNeedsDisplay];
}