2

編集:

ありがとう@BlackFrog。近づいたと思いますが、値はまだ取得されていません...

値は [progressController updateProgressSummary:...] 内のログで示されるように設定されますが、以下に示すように、progressUpdate initWithProgressUpdate:.... にログを記録すると nil になります。

私は、progressUpdate に設定されたプロパティと、progressUpdate の 3 つのコンポーネントのそれぞれに設定されたプロパティのどちらを使用するかについて、少し混乱しています。提案されているように、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 を呼び出し、現在の進行状況の詳細を渡します。次に、ProgressController のデリゲート (View Controller) で performSelectorOnMainThread を実行して、詳細を表示します。

単一の NSString を通過するときはすべて正常に機能していましたが、2 つの文字列と数値を渡す必要があり、 performSelectorOnMainThread は 1 つのオブジェクトしか渡せないため、これらをカスタム オブジェクト - ProgressUpdate にカプセル化しました。

データは ProgressController を正しく通過しますが、View Controller に表示されるまでには null です。さまざまな場所に 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];
}
4

2 に答える 2

2

init メソッドでは、ivar を割り当てるだけで、新しいオブジェクトに保持しません。次のように init メソッドをやり直します。

-(id) initWithProgressUpdate:(ProgressUpdate *)update {
    if ((self = [super init])) {
        summaryText = [update.summaryText copy];
        detailText = [update.detailText copy];
        percentComplete = [[NSNumber alloc] initWithFloat:[update.percentComplete floatValue];
    }
    return self;
}

ポイントのカップル:

  • init メソッドでアクセサを使用しないでください
  • init メソッドの名前を変更して、わかりやすくします
  • @property で、割り当てを保持に変更します
于 2011-04-19T22:36:15.450 に答える
0

「[progressUpdateForIssue release];」ステートメントを削除してみてください。メソッドで

'-(void) updateProgressSummary:(NSString *)summary detail:(NSString *)detail percentComplete:(NSNumber *)complete '.

また、ProgressUpdate クラスのプロパティ属性を「assign」から「retain」に変更します。dealloc メソッドでこれらのプロパティを解放できます。

幸運を。

于 2011-04-19T09:16:14.053 に答える