Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 使用委托、操作和队列_Objective C_Cocoa_Amazon S3_Amazon Web Services - Fatal编程技术网

Objective c 使用委托、操作和队列

Objective c 使用委托、操作和队列,objective-c,cocoa,amazon-s3,amazon-web-services,Objective C,Cocoa,Amazon S3,Amazon Web Services,我正在使用for iOS将文件上载到本地硬盘,并从本地硬盘下载到Amazon S3存储。我能够做到这一点,但我无法让S3代表在操作完成或导致错误时正确响应以提醒我 我有一系列要上传的文件。对于每个文件,我创建一个NSO操作,其中主例程主要包括: AmazonCredentials * credentials = [[AmazonCredentials alloc] initWithAccessKey:ACCESS_KEY_ID withSecretKey:SECRET_KEY];

我正在使用for iOS将文件上载到本地硬盘,并从本地硬盘下载到Amazon S3存储。我能够做到这一点,但我无法让S3代表在操作完成或导致错误时正确响应以提醒我

我有一系列要上传的文件。对于每个文件,我创建一个NSO操作,其中主例程主要包括:

    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];
这里,委托s3Delegate被创建为一个常规的,当操作完成时,它应该能够触发响应。我的每个NSOperations都添加到非并发执行操作的NSOperationQueue中。如果使用委托[putObjectRequest setDelegate:s3Delegate],则操作不起作用。如果我取消使用委托,操作将正确执行,但我无法收到任何操作响应,因为我没有委托

如果我完全取消NSOperationQueue的使用,并使用[putObjectRequest setDelegate:s3Delegate]委托,那么委托就可以正常工作

我的问题是,在队列中使用代理有什么不对?由于委托完全能够在不在队列中的情况下执行,这可能与不在主线程上执行有关吗?我确实希望能够使用队列来限制非并发操作的数量,但是我无法解决这个问题。我希望有人对这里发生的事情有一个想法,任何示例代码都将不胜感激。谢谢
干杯,Trond

在设置代理之后,aws sdk似乎会异步运行。 因此,为了让您的异步aws工作在异步NSO操作中,您需要使用一些魔法来等待aws完成:

在.nsh操作文件中,添加布尔值:

@interface UploadOperation : NSOperation <AmazonServiceRequestDelegate> {
    @private
    BOOL        _doneUploadingToS3;
}
不要忘记实现委托方法

-(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
}

注意:这种魔术可以用于任何异步执行但必须在NSO操作中实现的东西。

在设置委托后,aws sdk似乎会异步运行。 因此,为了让您的异步aws工作在异步NSO操作中,您需要使用一些魔法来等待aws完成:

在.nsh操作文件中,添加布尔值:

@interface UploadOperation : NSOperation <AmazonServiceRequestDelegate> {
    @private
    BOOL        _doneUploadingToS3;
}
不要忘记实现委托方法

-(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
}

注意:这种魔术可以用于任何异步执行的东西,但必须在NSO操作中实现。

谢谢!它完全符合你的建议。使此工作正常的技巧似乎是代码:do{[[NSRunLoop currentlunloop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];}while_doneUploadingToS3;我尝试在没有此代码段的情况下运行该操作,但它不起作用。当我包含它时,代理可以无缝地工作。你能给我解释一下为什么这个代码如此重要以及它的作用吗?再次感谢!。干杯,Trond此循环等待“完成”PLOADINGTOS3设置为“是”。但在那之前,它不会使CPU过载。当AWS SDK的一个完成方法被激发时,_doneUploadingToS3被设置为YES,主方法的其余部分被执行。非常感谢!这正是我的问题。标记:AmazonServiceRequestDelegate不工作Nsoperation NSOperationQueue只是一个简短的说明如果您使用的AmazonServiceRequestDelegate具有多部分上载,您还需要将代码移动到通常将部分编号添加到完成请求的位置,例如。[completionRequest addPartWithPartNumber:partRequest.partNumber withETag:mpResponse.etag];调用委托中的didCompleteWithResponse方法,因为您将从s3客户端上的uploadPart方法中获得零返回。谢谢!它与您的建议完美结合。使此工作正常的技巧似乎是代码:do{[[NSRunLoop currentRunLoop]运行模式:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];}while!\u doneUploadingToS3;我尝试在没有此代码段的情况下运行此操作,但它不起作用。当我包含此代码时,代理可以无缝工作。您能否向我解释为什么此代码如此重要以及它的作用?再次感谢!干杯,trondt此循环等待将\u doneUploadingToS3设置为“是”。在此之前,它将循环,而不会使您过载r CPU。当AWS SDK的一个完成方法被触发时,_doneUploadingToS3被设置为YES,主方法的其余部分被执行。非常感谢!这正是我的问题。标记:AmazonServiceRequestDelegate不工作Nsoperation NSOperationQueue如果您使用带有m多部分上载时,您还需要将代码移到通常将部分编号添加到完成请求的位置,例如[completionRequest addPartWithPartNumber:partRequest.partNumber withETag:mpResponse.etag];移到委托中的didCompleteWithResponse方法,因为您将从s3客户端上的uploadPart方法获得零返回。