我有一个返回布尔值的方法。如果已从URL中找到至少一个图像/资产,则应返回true。代码如下所示。 在块中,当我打印数组中的对象计数时,它会正确打印。但是,在块外部,计数为零,并且它不会进入if块,并且该方法始终返回FALSE。我想这是因为函数在块执行之前返回。我该如何解决这个问题?如果在块内的self.imageURLs中添加了至少一个URL,我如何确保该方法返回true?
-(BOOL)getPhotos
{
self.imagesFound = FALSE;
//get all image url's from database
//for each row returned do the following:
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *URLString = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 0)];
NSURL *imageURL = [NSURL URLWithString:URLString];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:imageURL resultBlock:^(ALAsset *asset)
{
if (asset) {
//if an image exists with this URL, add it to self.imageURLs
[self.imageURLs addObject:URLString];
NSLog(@"no. of objects in array: %lu", (unsigned long)self.imageURLs.count);
}
}
failureBlock:^(NSError *error)
{
// error handling
NSLog(@"failure-----");
}];
}
if (self.imageURLs.count > 0) {
NSLog(@"self.imageURLs count = %lu", (unsigned long)self.imageURLs.count);
self.imagesFound = TRUE;
}
else
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Sorry!" message:@"No photos found" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
return self.imagesFound;
}
答案 0 :(得分:0)
因此,块可以维护一组可以使用的状态(数据) 在执行时影响行为。
在块执行完成后写入所有代码并发送通知而不是返回值。
[library assetForURL:imageURL resultBlock:^(ALAsset *asset)
{
if (asset)
{
//if an image exists with this URL, add it to self.imageURLs
[self.imageURLs addObject:URLString];
self.imagesFound = TRUE;
//send a notificaton from here as TRUE,
}
}failureBlock:^(NSError *error)
{
//self.imagesFound = NO;
//display error alert.
//send a notificaton from here as FALSE,
}];
答案 1 :(得分:0)
这可能是因为块有时是异步的,即在执行
之后[library assetForURL:imageURL resultBlock:^(ALAsset *asset).....
它不会等待完成块的执行,它会立即执行下一个语句。
检查哪个日志首先打印
NSLog(@"no. of objects in array: %lu", (unsigned long)self.imageURLs.count);
或
之后的日志[library assetForURL:imageURL resultBlock:^(ALAsset *asset).....
答案 2 :(得分:0)
这种事情几乎就是块上的委托或完成处理程序的用途。因为您的块是异步的,所以在您设置布尔值之前,它会继续运行并执行其余的代码。
要通过委托来做,你会:
创建一个类,在实例化时执行您希望它在后台线程上执行的操作,并将调用者设置为委托。
完成后,回调委托方法,然后从那里开启相应的脚本。
或者只是添加一个完成处理程序,它将启动你的其余代码,这取决于你当前没有得到的结果。
根据我的经验,尽管代表团需要花费更长的时间来编写代码,并且如果您是新手,但是更难以理解,这会使您的代码更具可重用性,并且可以更好地抽象以便能够在其他地方重复使用在您的应用程序中需要相同的异步计数或操作。