我正在尝试创建一个方法,该方法将返回给定资产 url 的 ALAsset。 (我需要稍后上传资产,并希望在结果块之外执行此操作。)
+ (ALAsset*) assetForPhoto:(Photo*)photo
{
ALAssetsLibrary* library = [[[ALAssetsLibrary alloc] init] autorelease];
__block ALAsset* assetToReturn = nil;
NSURL* url = [NSURL URLWithString:photo.assetUrl];
NSLog(@"assetForPhoto: %@[", url);
[library assetForURL:url resultBlock:^(ALAsset *asset)
{
NSLog(@"asset: %@", asset);
assetToReturn = asset;
NSLog(@"asset: %@ %d", assetToReturn, [assetToReturn retainCount]);
} failureBlock:^(NSError *error)
{
assetToReturn = nil;
}];
NSLog(@"assetForPhoto: %@]", url);
NSLog(@"assetToReturn: %@", assetToReturn); // Invalid access exception coming here.
return assetToReturn;
}
问题是资产返回给出 EXC_BAD_ACCESS。
如果我尝试从块内部分配指针,是否会出现问题?我看到了一些块的示例,但它们总是具有简单类型,例如整数等。
一些东西:
- You must保持
ALAssetsLibrary
周围的实例创建了ALAsset
只要您使用该资产。
- You must注册观察员
ALAssetsLibraryChangedNotification
,当收到任何ALAsset
您拥有的和任何其他 AssetsLibrary 对象都需要重新获取,因为它们将不再有效。这随时可能发生。
- You 不应该期望
-assetForURL:resultBlock:failureBlock:
,或任何带有failureBlock:
是同步的。他们可能需要提示用户访问库,并且并不总是立即执行他们的块。最好将成功时需要发生的操作放在成功块本身中。
- 仅当您绝对必须在应用程序中使此方法同步(我建议您不要这样做)时,您才需要在调用后等待信号量
assetForURL:resultBlock:failureBlock:
如果您最终阻塞了主线程,则可以选择旋转运行循环。
以下实现应该满足所有情况下的同步调用,但实际上,您应该努力使代码异步。
- (ALAsset *)assetForURL:(NSURL *)url {
__block ALAsset *result = nil;
__block NSError *assetError = nil;
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[[self assetsLibrary] assetForURL:url resultBlock:^(ALAsset *asset) {
result = [asset retain];
dispatch_semaphore_signal(sema);
} failureBlock:^(NSError *error) {
assetError = [error retain];
dispatch_semaphore_signal(sema);
}];
if ([NSThread isMainThread]) {
while (!result && !assetError) {
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
else {
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
dispatch_release(sema);
[assetError release];
return [result autorelease];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)