24

NSURLConnection オブジェクトを UIProgressView と統合しようとしているので、バックグラウンドでファイルのダウンロードが行われている間にユーザーを更新できます。

バックグラウンドでファイルをダウンロードするために別のオブジェクトを作成しましたが、UIProgressView オブジェクトの進行状況プロパティを正しい値で更新する方法を理解するのに問題があります。おそらく非常に単純なことですが、グーグルで調べてもわかりません。

私が持っているコードは次のとおりです。

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    [self.resourceData setLength:0];
    self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
    NSLog(@"content-length: %d bytes", self.filesize);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [self.resourceData appendData:data];

    NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]];
    NSLog(@"resourceData length: %d", [resourceLength intValue]);
    NSLog(@"filesize: %d", self.filesize);
    NSLog(@"float filesize: %f", [self.filesize floatValue]);
    progressView.progress = [resourceLength floatValue] / [self.filesize floatValue];
    NSLog(@"progress: %f", [resourceLength floatValue] / [self.filesize floatValue]);
}

ご覧のとおり、resourceDataメンバー変数は、ダウンロード中のファイル データを保持します。filesizeメンバー変数は、Web サービスによって Content-Length ヘッダーに返される、ファイルのフル サイズを保持します

すべて問題なく動作します。didReceiveDataを複数回実行してダウンロードしたデータを取得し続けますが、進行状況の値を計算しようとすると、適切な値が返されません。コンソール ログに記録される内容の小さなサンプルについては、以下を参照してください。

content-length: 4687472 bytes
resourceData length: 2904616
filesize: 4687472
float filesize: -1.000000
progress: -2904616.000000

参考までに、progressView.progressは float です。filesizeは long long を保持する NSNumber です。最後に、resourceLengthは NSUInteger を保持する NSNumber です。

ここで何が欠けていますか?

4

3 に答える 3

29

ここで何が欠けているのかわかりませんが、filesize-1 であることは問題のようです。API ドキュメントexpectedContentLengthには、利用できない可能性がありNSURLResponseUnknownLength、これらの場合に返さ れることが明確に記載されています。NSURLResponseUnknownLengthと定義されている:

#define NSURLResponseUnknownLength ((long long)-1)

このような場合、正確な進行状況を取得できません。これを処理し、ある種の不確定な進行状況メーターを表示する必要があります。

于 2008-11-23T19:58:58.183 に答える
6

ファイルサイズを間違って印刷していると思います。self.filesizeが実際に である場合はNSNumber、次の形式を使用して出力し%@ます。これは、プリミティブではなくオブジェクトであるためです。

NSLog(@"filesize: %@", self.filesize);

を使用する%dと、self.filesizeのポインター値を出力するだけです。実際の long long 値を出力するには、%lli(%dは 32 ビット値のみ) を使用します。

NSLog(@"filesize: %lli", [self.filesize longLongValue]);

したがって、 self.filesize は実際には-1 であり、除算は正しいです。

于 2008-11-24T01:04:02.937 に答える
0

あなたのコードでは、filesize は NSNumber オブジェクト (!) のようです。そう

NSLog(@"filesize: %d", self.filesize);

NSLog(@"content-length: %d bytes", self.filesize);

そのオブジェクトのアドレス (id) のようなもの (またはその他のもの) を報告する可能性があります。これは

filesize: 4687472

分かりますか。他の人が指摘したように、応答によって返されるファイル サイズは実際には -1 です。つまり、

NSURLResponseUnknownLength

つまり、サーバーはファイル サイズを返しませんでした。

于 2010-07-25T12:59:20.023 に答える