mit*_*tnt 5 cocoa-touch objective-c-blocks alasset
我正在尝试创建一个方法,它将返回给定资产网址的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;
}
Run Code Online (Sandbox Code Playgroud)
问题是assetToReturn提供了EXC_BAD_ACCESS.
如果我尝试从块内部指定指针,是否有问题?我看到了一些块的例子,但它们总是有简单的类型,如整数等.
一些东西:
ALAssetsLibrary周围创建的实例ALAsset,只要您使用的资产.ALAssetsLibraryChangedNotification,当收到ALAsset您的任何内容时,任何其他AssetsLibrary对象都需要重新获取,因为它们将不再有效.这可以随时发生.-assetForURL:resultBlock:failureBlock:具有a的AssetsLibrary方法或任何AssetsLibrary方法failureBlock:是同步的.他们可能需要提示用户访问库,并且不会立即执行其块.最好在成功块本身中将需要执行的操作放在成功块上.assetForURL:resultBlock:failureBlock:并且如果最终阻塞主线程,可以选择旋转runloop.以下实现应满足所有情况下的同步调用,但实际上,您应该非常努力地使代码异步.
- (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];
}
Run Code Online (Sandbox Code Playgroud)