gpt4 book ai didi

iOS:我可以从一个 block 中执行一个方法吗?或者这是不正确的?

转载 作者:行者123 更新时间:2023-11-29 02:57:49 24 4
gpt4 key购买 nike

self.FfAppClient 中的两种方法,一种用于上传,一种用于下载,在单独的 App 中工作,其中 uploadFiledownloadFile 被触发通过 View Controller 上的按钮。上传完成后,用户会有视觉反馈,因此可以继续按下按钮下载文件。

在下面的应用程序中,我测试了 uploadFiledownloadFile 可以单独工作,但是当我使用下面的代码段时,上传有时会失败并且下载从不工作。

我试图等到我知道上传完成(self.FfAppClient uploadFile 给出成功),然后开始下载。这是完全错误的使用 block 的方式吗?更重要的是,是否有理由在 block 内包含 [self downloadImage:[NSString stringWithFormat:@"ımage id=%d",entryID]];行不通?

- (void)uploadThenDownloadImage:(UIImage*)image usingImagePath:(NSString*)imagePath
{
NSData *imageData = UIImageJPEGRepresentation(image, 1);
[self.FfAppClient uploadFile:imagePath withContent:imageData success:^(id response) {
NSInteger entryID = [[response objectForKey:@"id"] integerValue];
[self downloadImage:[NSString stringWithFormat:@"ımage id=%d",entryID]];

} failure:^(NSError *error) {
NSLog(@"Upload error: %@", error.description);
}];

}

- (void)downloadImage:(NSString*)fileID
{
[self.FfAppClient downloadFile:fileID success:^(id response) {
NSString* suggested = [response objectForKey:@"suggested"];
NSString* temp = [response objectForKey:@"temp"];
[self moveTempFileNamed:suggested toIncomingFolderFromTemporaryLocation:temp];

} failure:^(NSError *error) {
NSLog(@"Download error: %@", error.description);
} progress:^(float prc) {
NSLog(@"Download amount: %@", [NSString stringWithFormat:@"downloaded %.02f", prc]);
}];
}

我在下载部分得到的错误是:

-[FfAppClient URLSession:task:didCompleteWithError:]: error: Error Domain=NSURLErrorDomain Code=-1000 "bad URL" UserInfo=0x1383b500 {NSUnderlyingError=0x15370380 "bad URL", NSLocalizedDescription=bad URL}

有时,上传也会失败,因为在 success block 中的响应给出了无意义的字符串,例如 ;8@c1jL2gZK3yWziVNuY-h1btzGG.t!u5zoRW2MV 而不是指服务器上图片的名称。

是否有其他方法可以实现此目的或我的代码失败的原因?

**

编辑:uploadFiledownloadFile方法:

**

- (void)uploadFile:(NSString *)filename withContent:(NSData*)content success:(FfSuccessBlock)successBlock failure:(FfFailBlock)failBlock
{
if ( ![self isConnected] )
{
NSError *error = [NSError errorWithDomain:@"Not connected" code:0 userInfo:nil];
failBlock(error);
return;
}

NSString *urlFormat = [NSString stringWithFormat:@"%@%@/%@", kFfPicsBasePath, kFfPutFileURL, kFfSubscriptionId];
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];

NSMutableURLRequest* request = [self signedRequestWithURL:[NSURL URLWithString:urlFormat] andMethod:@"POST" andParams:params];
[request setCachePolicy:NSURLRequestReloadIgnoringCacheData];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
NSString* boundary = [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()];
[request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"];
// Body part for the attachament. This is an image.
NSMutableData *body = [NSMutableData data];
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n", @"docfile", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:content];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

request.HTTPBody = body;

self.currentSuccessBlock = successBlock;
self.currentFailBlock = failBlock;
__block FfAppClient* me = self;

self->_resTask = [self->_resSession dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
int statusCode = httpResponse.statusCode;
if ( !error )
{
if ( statusCode >= 400 )
{
NSString* bodyError = data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : [NSString stringWithFormat:NSLocalizedString(@"HTTP Error: %d", @"FfResourceHTTPErrorDomain description"), statusCode];
NSDictionary *errorInfo =[NSDictionary dictionaryWithObject:bodyError forKey:NSLocalizedDescriptionKey];
error = [NSError errorWithDomain:@"Failed URL" code:statusCode userInfo:errorInfo];
}
else if ( ![[response MIMEType] isEqualToString:@"application/json"] || [data length] == 0 )
{
NSString* bodyStr = data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : @"";
NSString* bodyError = [NSString stringWithFormat:NSLocalizedString(@"HTTP Content Type Error: %@/n%@", @"FfOResource2HTTPErrorDomain description"), [response MIMEType], bodyStr];
NSDictionary *errorInfo =[NSDictionary dictionaryWithObject:bodyError forKey:NSLocalizedDescriptionKey];
error = [NSError errorWithDomain:@"Failed URL" code:555 userInfo:errorInfo];
}
}
id jsonResponse = nil;
if ( !error )
{
jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
}
if ( error )
{
data = nil;
if ( me.currentFailBlock ) {
__block NSError* blockError = error;
dispatch_sync(dispatch_get_main_queue(), ^{ me.currentFailBlock( blockError ); });
}
}
else
{
if ( me.currentSuccessBlock )
{
dispatch_sync(dispatch_get_main_queue(), ^{ me.currentSuccessBlock(jsonResponse); });
}
}
me->_resTask = nil;
[me clearBlocks];
}];
[self->_resTask resume];
}

- (void)downloadFile:(NSString *)fileId success:(FfSuccessBlock)successBlock failure:(FfFailBlock)failBlock progress:(FfProgressBlock)progress;
{
if ( ![self isConnected] )
{
NSError *error = [NSError errorWithDomain:@"Not connected" code:0 userInfo:nil];
failBlock(error);
return;
}

NSString *urlFormat = [NSString stringWithFormat:@"%@%@/%@", kFfPicsBasePath, kFfGetFileURL, fileId];
NSLog(@"fileid: %@", fileId);
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];

NSMutableURLRequest* request = [self signedRequestWithURL:[NSURL URLWithString:urlFormat] andMethod:@"GET" andParams:params];

NSLog(@"---> Request: %@", request);

[request setCachePolicy:NSURLRequestReloadIgnoringCacheData];

self.currentSuccessBlock = successBlock;
self.currentFailBlock = failBlock;
self.currentProgressBlock = progress;

self->_resTask = [self->_resSession downloadTaskWithRequest:request];
[self->_resTask resume];
}

最佳答案

听起来像是内存管理或多线程问题;从 block 内调用方法很好,但可能不是您在此处使用 FfAppClient 执行的操作。在上传 _resTask 完全完成之前,您正在开始一个下载任务,该任务将覆盖尚未完成的上传调用已设置的大多数 ivar(这可能会导致对象被释放)并且在另一个线程上任务正在运行。可能需要对 FfAppClient 代码进行重大重写以确保其安全,但您可以尝试以下两种快速破解方法:

1) 如果可能,使用两个不同的FfAppClient

注意下面代码中的FfAppClientAFfAppClientB:

- (void)uploadThenDownloadImage:(UIImage*)image usingImagePath:(NSString*)imagePath
{
NSData *imageData = UIImageJPEGRepresentation(image, 1);
[self.FfAppClientA uploadFile:imagePath withContent:imageData success:^(id response) {
NSInteger entryID = [[response objectForKey:@"id"] integerValue];
[self downloadImage:[NSString stringWithFormat:@"ımage id=%d",entryID]];

} failure:^(NSError *error) {
NSLog(@"Upload error: %@", error.description);
}];
}

- (void)downloadImage:(NSString*)fileID
{
[self.FfAppClientB downloadFile:fileID success:^(id response) {
NSString* suggested = [response objectForKey:@"suggested"];
NSString* temp = [response objectForKey:@"temp"];
[self moveTempFileNamed:suggested toIncomingFolderFromTemporaryLocation:temp];

} failure:^(NSError *error) {
NSLog(@"Download error: %@", error.description);
} progress:^(float prc) {
NSLog(@"Download amount: %@", [NSString stringWithFormat:@"downloaded %.02f", prc]);
}];
}


2) 分派(dispatch)异步并允许第一个任务在开始第二个任务之前完全完成

由于成功和失败 block 是同步分派(dispatch)给 main 的,请尝试以下操作:

- (void)uploadThenDownloadImage:(UIImage*)image usingImagePath:(NSString*)imagePath
{
NSData *imageData = UIImageJPEGRepresentation(image, 1);
[self.FfAppClientA uploadFile:imagePath withContent:imageData success:^(id response) {
dispatch_async(dispatch_get_main_queue(), ^{
NSInteger entryID = [[response objectForKey:@"id"] integerValue];
[self downloadImage:[NSString stringWithFormat:@"ımage id=%d",entryID]];
});
} failure:^(NSError *error) {
NSLog(@"Upload error: %@", error.description);
}];

}


不过,这些都是相当快速的技巧,而不是真正的解决方案。

关于iOS:我可以从一个 block 中执行一个方法吗?或者这是不正确的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23685331/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com