objective-c - 使用委托(delegate)、操作和队列

标签 objective-c cocoa amazon-s3 amazon-web-services

我正在使用AWS SDK用于 iOS 将文件上传到本地硬盘到 Amazon S3 存储以及从本地硬盘下载文件。我有能力完成这项工作,但我无法让 S3 委托(delegate)做出正确响应,以便在操作完成或导致错误时提醒我。

我有一组要上传的文件。对于每个文件,我创建一个 NSOperation,其中 main 例程主要由以下部分组成:

    AmazonCredentials * credentials = [[AmazonCredentials alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];
    putObjectRequest = [[S3PutObjectRequest alloc] initWithKey:pathCopy inBucket:[self bucket]];
    putObjectRequest.filename = pathSource;
    putObjectRequest.credentials=credentials;
    [putObjectRequest setDelegate:s3Delegate];

此处,委托(delegate) (s3Delegate) 被创建为常规 AmazonServiceRequestDelegate当操作完成时,它应该能够发出响应。我的每个 NSOperations 都添加到我的 NSOperationQueue 中,它非并发地执行操作。如果我使用委托(delegate) [putObjectRequest setDelegate:s3Delegate] 操作将不起作用。如果我删除委托(delegate)的使用,操作将正确执行,但我无法收到对操作的任何响应,因为我没有委托(delegate)。

如果我完全删除 NSOperationQueue 的使用并使用 [putObjectRequest setDelegate:s3Delegate] 委托(delegate)可以正常工作。

我的问题是我在队列中使用委托(delegate)时做错了什么?由于委托(delegate)完全能够在不在队列中时执行,这是否与不在主线程上执行有关?我真的希望能够使用队列来限制非并发操作的数量,但是我无法弄清楚这一点。我希望有人知道这里发生了什么,并且任何示例代码将不胜感激。谢谢! 干杯,特隆德

最佳答案

在您设置委托(delegate)之后,aws sdk 似乎会异步运行。 因此,为了让您的异步 aws 内容在(异步)NSOperation 中工作,您必须使用一些魔法来等待 AWS 完成:

在您的 .h NSOperation 文件中,添加一个 bool 值:

@interface UploadOperation : NSOperation <AmazonServiceRequestDelegate> {
    @private
    BOOL        _doneUploadingToS3;
}

在你的 .m 文件中,你的 main 方法将如下所示:

- (void) main
{   
    ....  do your stuff …..

    _doneUploadingToS3 = NO;

    S3PutObjectRequest *por = nil;
    AmazonS3Client *s3Client = [[AmazonS3Client alloc] initWithAccessKey:ACCESS_KEY withSecretKey:SECRET_KEY];
    s3Client.endpoint = endpoint;

    @try {
        por = [[[S3PutObjectRequest alloc] initWithKey:KEY inBucket:BUCKET] autorelease];
        por.delegate = self;
        por.contentType = @"image/jpeg";
        por.data = _imageData;

        [s3Client putObject:por];
    }
    @catch (AmazonClientException *exception) {
        _doneUploadingToS3 = YES;
    }

    do {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    } while (!_doneUploadingToS3);

    por.delegate = nil;

    ....  continue with your stuff ….
}

不要忘记实现你的委托(delegate)方法

-(void)request:(AmazonServiceRequest *)request didCompleteWithResponse:(AmazonServiceResponse *)response
{
    _doneUploadingToS3 = YES;
}

-(void)request:(AmazonServiceRequest *)request didFailWithError:(NSError *)error 
{
    _doneUploadingToS3 = YES;
}

-(void)request:(AmazonServiceRequest *)request didFailWithServiceException:(NSException *)exception 
{
    _doneUploadingToS3 = YES;
}

- (void) request:(AmazonServiceRequest *)request didSendData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
    // Do what you want
}

-(void)request:(AmazonServiceRequest *)request didReceiveResponse:(NSURLResponse *)response
{
    // Do what you want
}

-(void)request:(AmazonServiceRequest *)request didReceiveData:(NSData *)data
{
    // Do what you want
}

注意:这个魔法适用于任何异步执行但必须在 NSOperation 中实现的东西。

关于objective-c - 使用委托(delegate)、操作和队列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8230870/

相关文章:

objective-c - UIButton 调用选择器会使应用程序崩溃

php - Laravel 5.2-调用未定义的方法 Illuminate\Support\Facades\Response::header()

amazon-s3 - 使用 amazon s3 和 cloudfront 作为 CDN

java - 获取预签名 URL 时应用程序在 firestick 2nd gen 上崩溃

ios - 如何在没有 Mac Developer 程序成员(member)资格的情况下使用 NSLogger Desktop Client

iphone - 在联系页面添加地址簿

iphone - 在 xCode 中加载自定义 UIFonts

objective-c - 在这里过度释放?

cocoa - 让 cocoa 应用程序响应自动化操作

objective-c - 为什么这不起作用? - 将数据写入plist