gpt4 book ai didi

objective-c - 异步传递值

转载 作者:行者123 更新时间:2023-11-28 18:25:27 24 4
gpt4 key购买 nike

我有以下使用 block 和完成处理程序的方法:

    // Returns YES if photo is stored in a virtual vacation.
- (BOOL) photoIsOnVacation
{
__block BOOL photoOnFile = NO;

// Identify the documents folder URL.
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSError *errorForURLs = nil;
NSURL *documentsURL = [fileManager URLForDirectory:NSDocumentDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:NO
error:&errorForURLs];
if (documentsURL == nil) {
NSLog(@"Could not access documents directory\n%@", [errorForURLs localizedDescription]);
} else {

// Retrieve the vacation stores on file.
NSArray *keys = [NSArray arrayWithObjects:NSURLLocalizedNameKey, nil];
NSArray *vacationURLs = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:documentsURL
includingPropertiesForKeys:keys
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
if (!vacationURLs) photoOnFile = NO;
else {

// Search each virtual vacation for the photo.
for (NSURL *vacationURL in vacationURLs) {
NSError *errorForName = nil;
NSString *vacationName = nil;
[vacationURL getResourceValue:&vacationName forKey:NSURLNameKey error:&errorForName];
[VacationHelper openVacationWithName:vacationName usingBlock:^(UIManagedDocument *vacationDocument) {
NSError *error = nil;
NSManagedObjectContext *moc = vacationDocument.managedObjectContext;

// Build fetch request.
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Photo"];
NSString *currentPhotoID = [self.chosenPhoto objectForKey:FLICKR_PHOTO_ID];
request.predicate = [NSPredicate predicateWithFormat:@"unique = %@", currentPhotoID];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"unique" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

// Execute fetch request.
NSArray *checkPhotos = [moc executeFetchRequest:request error:&error];
if (error) {
NSLog(@"Error searching for photo:%@",error);
} else {
Photo *checkPhoto = [checkPhotos lastObject];
if ([checkPhoto.unique isEqualToString:currentPhotoID]) photoOnFile = YES;
}
}];
if (photoOnFile) break;
}
}
}
return photoOnFile;
}

我的问题是 photoOnFile 始终为 false,因为执行到达包含获取请求的 block 之前的返回。我尝试将 photoOnFile 分配嵌入 dispatch_async(dispatch_get_main_queue(),^{ 但这没有帮助。任何指导表示赞赏。

更新:这里是成功合并了 Ken 推荐的解决方案的重写代码:

    - (void)checkIfPhotoIsOnVacationAndDo:(void(^)(BOOL photoIsOnVacation))completionBlock
{
__block BOOL photoIsOnVacation = NO;

// Identify the documents folder URL.
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSError *errorForURLs = nil;
NSURL *documentsURL = [fileManager URLForDirectory:NSDocumentDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:NO
error:&errorForURLs];
if (documentsURL == nil) {
NSLog(@"Could not access documents directory\n%@", [errorForURLs localizedDescription]);
} else {

// Retrieve the vacation stores on file.
NSArray *keys = [NSArray arrayWithObjects:NSURLLocalizedNameKey, nil];
NSArray *vacationURLs = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:documentsURL
includingPropertiesForKeys:keys
options:NSDirectoryEnumerationSkipsHiddenFiles
error:nil];
if (!vacationURLs) photoIsOnVacation = NO;
else {

// Search each virtual vacation for the photo.
for (NSURL *vacationURL in vacationURLs) {
NSError *errorForName = nil;
NSString *vacationName = nil;
[vacationURL getResourceValue:&vacationName forKey:NSURLNameKey error:&errorForName];
[VacationHelper openVacationWithName:vacationName usingBlock:^(UIManagedDocument *vacationDocument) {
NSError *error = nil;
NSManagedObjectContext *moc = vacationDocument.managedObjectContext;

// Build fetch request.
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Photo"];
NSString *currentPhotoID = [self.chosenPhoto objectForKey:FLICKR_PHOTO_ID];
request.predicate = [NSPredicate predicateWithFormat:@"unique = %@", currentPhotoID];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"unique" ascending:YES];
request.sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

// Execute fetch request.
NSArray *checkPhotos = [moc executeFetchRequest:request error:&error];
if (error) {
NSLog(@"Error searching for photo:%@",error);
} else {
Photo *checkPhoto = [checkPhotos lastObject];
if ([checkPhoto.unique isEqualToString:currentPhotoID]) {
photoIsOnVacation = YES;
completionBlock(photoIsOnVacation);
}
}
}];
if (photoIsOnVacation) break;
}
completionBlock(photoIsOnVacation);
}
}
}

最佳答案

异步性趋于传播。一旦将 API 设为异步,其所有调用方也必须重新设计为异步工作。因此,像您的 - (BOOL) photoIsOnVacation 这样的方法是站不住脚的,因为它的接口(interface)是同步的——调用者希望在调用完成后立即得到答案——但实现不是那样工作的。

您必须重新设计为类似 - (void) checkIfPhotoIsOnVacationAndDo:(void(^)(BOOL photoIsOnVacation))block 的内容。这从调用者那里获取一个 block ,并在知道答案时调用该 block 。

关于objective-c - 异步传递值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10970832/

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