インジケータにコピーしたbytesを表示していくわけだが、これがどうもうまくいかないので調べてみる。
FSCopyObjectAsyncのcallbackには自クラスのselfを引数で渡して、自クラスのメソッドをさらにcallbackする。このほうがIBOutletとかをいじるのが簡単だし、なにかとCocoaスタイルのほうが初心者には都合がいい。で、そのcallbackのcallbackメソッドの中で
bytesCompleted = (CFNumberRef) CFDictionaryGetValue(statusDictionary, kFSOperationBytesCompleteKey);という風にコピー済みbyteを得ているが、複数ファイルをいっぺんに非同期コピーしていると「どのファイルが、どれだけコピー済みか」がわからない。
そこでcallbackの中でコピー中のファイルのURLを得るようにして、それをcallbackのcallback(・・ええい、面倒くさい)に渡すようにしてみた。
だからcallbackのcallbackはこうなっている。
FileOperationStage: (FSFileOperationStage) stage Status:(OSStatus) error DictionaryRef:(CFDictionaryRef)statusDictionary currentURL:(NSURL*)aURL{最後のaURLが現在コピー中のファイルのURL。で、callbackが呼ばれるたびにこのURLの中身をNSLogしてみると、なんと、「コピー元」と「コピー先」の両方のファイルについて、それぞれcallbackが呼ばれていることがわかった。
つまり、
/hoge/hoge.txt
から
/hage/hoge.txt
にコピーするとして、コピー元/hoge/hoge.txtが100Kbytes分転送されたらcallbackが呼ばれ、コピー先/hage/hoge.txtが100K転写されたらもう1回callbackが呼ばれ、単純に「コピー済みbytes」を合計すると2倍の数値を得ることになってしまう。だからインジケータがすぐに動かなくなるのか。
そこで
[copyComplatedbytesOfFiles setObject:compBytes forKey:[[aURL path] lastPathComponent]];
みたいなNSMutableDictionaryを作っておいて、hoge.txtが何byte転送済みかを記録しておくことにしてみた。
で、
for(NSNumber* num in bytesArray){
allFileComplatedByte+=[num doubleValue];
}
辞書内のコピー済みbytesを集計してインジケータに設定する、と。
たったこれだけのことだけど、思った通りの動作をしてうれしい。問題はコードがめちゃくちゃ汚いことだな。(^^;)書きなおそう。
あとはこの動作全体をNSOperationに入れてやればいいのだろうが、非同期コピーなので大きなファイルをコピー中に他のファイルをコピーしても十分動作する。これでいいかなあ。
問題はダイアログがぴったり重なって表示されることだなあ。
0 件のコメント:
コメントを投稿