0

操作の最後に関連するメッセージを表示するには、複数のファイルをアップロードし、それらの進行状況を追跡し、完了ブロックと失敗ブロックにサブスクライブする必要があります。

独自の AFHTTPClient ラッパーを作成し、次のメソッドを作成しました。

- (void) uploadFiles:(NSArray*)files
                path:(NSString*)path
          parameters:(NSDictionary*)parameters
       progressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block
             success:(void (^)(AFHTTPRequestOperation *, id))success failure:(void (^)(AFHTTPRequestOperation *, NSError *))failure
{
    NSMutableURLRequest *request =
    [self multipartFormRequestWithMethod:@"POST"
                                    path:path
                              parameters:parameters
               constructingBodyWithBlock:
     ^(id <AFMultipartFormData>formData) {

         for (CRLMultiPartFile *file in files) {
             NSAssert(file.name, @"Name cannot be nil");
             NSAssert(file.file, @"Nothing found to upload");
             NSAssert(file.filename, @"FileName cannot be nil");
             NSAssert(file.mimeType, @"Must set Mime-Type for %@", file.filename);
             [formData appendPartWithFileData:file.file name:file.name fileName:file.filename mimeType:file.typeString];
         }
    }];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [operation setUploadProgressBlock:block];
    [operation setCompletionBlockWithSuccess:success failure:failure];
    [self enqueueHTTPRequestOperation:operation];
}

このメソッドを呼び出すView Controllerは割り当て解除されないため、含まれているすべての画像もメモリに保持され、メモリリークが発生し、最終的にメモリ警告が発生します。

プロファイリングを実行すると、操作全体の最後に、View Controller の値がrefCount1 であることがわかります。

ファイルをアップロードする呼び出しをコメントアウトすると、すべて正常に動作します。

これがコントローラーのコードです。プログレス ブロックを使用して、UI の要素を更新します。

NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
ContactModel *model = (ContactModel*)[self.contacts lastObject];
[params setObject:model.phone forKey:@"receiver"];

__block typeof(self) sSelf = self;

[[JMClient sharedClient] uploadFiles:files
                                path:@"picture_share/"
                          parameters:params
                       progressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {

                           CGFloat progPercent = ceilf(((CGFloat)totalBytesWritten / (CGFloat)totalBytesExpectedToWrite) * 100);

                           CGFloat widthToCut = (progPercent * sSelf.progWidth) / 100;

                           CGRect frame = sSelf.progresViewBG.frame;
                           frame.size.width = (sSelf.progWidth  - widthToCut);
                           frame.origin.x   = (sSelf.progOrigin + widthToCut);
                           sSelf.progresViewBG.frame = frame;

                           sSelf.progLabel.text = [NSString stringWithFormat:@"%i%%", (int)progPercent];

                           frame = sSelf.progTipView.frame;
                           frame.origin.x = (sSelf.progresViewBG.frame.origin.x - frame.size.width/2);
                           sSelf.progTipView.frame = frame;

                           frame = sSelf.progLabel.frame;
                           frame.origin.x = (sSelf.progresViewBG.frame.origin.x - frame.size.width/2);
                           sSelf.progLabel.frame = frame;

                       } success:^(AFHTTPRequestOperation *success, id reponse) {

                           CGRect frame = sSelf.progresViewBG.frame;
                           frame.size.width = 0;
                           frame.origin.x = sSelf.progOrigin;
                           sSelf.progresViewBG.frame = frame;
                           [sSelf.cancelButton setImage:[UIImage imageNamed:@"trnsfr_prgss_complt.png"] forState:UIControlStateNormal];

                           [sSelf performSelector:@selector(hideAwayProgressBars) withObject:nil afterDelay:3];

                       } failure:^(AFHTTPRequestOperation *failure, NSError *error) {

                           [Mediator showMessage:TGLocalizedString(kMessageKeyForUploadingFailed)];
                           [sSelf performSelector:@selector(hideAwayProgressBars) withObject:nil afterDelay:3];

                       }];

self.operation = [[self.client.sharedClient.operationQueue operations] lastObject];

- (void) hideAwayProgressBars
{
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotifcationKeyForPhotoUploadComplete object:nil];
}

通知は親コントローラーによって受信され、このコントローラーのビューがスーパービューから削除され、nil に設定されます。

PS CRLMultiPartFile は、アップロードするファイルの属性を保持するカスタム クラスです。

4

1 に答える 1

1

ARC を使用している場合は、__weak代わりに を使用して、ブロック内で__blockキャプチャしないようにする必要があります。self

于 2013-04-15T05:55:19.043 に答える