我在这个错误时间里遇到了困难,最后我深入研究了这段代码。当您“运行”应用程序时,此代码很有效,但在“测试”时会导致应用程序崩溃。我用Google搜索并发现了这个问题:
Occasional errors when running OCUnit application test suite on device
但解决方案对我不起作用; - (
我是一名新手iOS开发人员,所以我不确定这段代码是否会造成恶意。谁能告诉我:
application:didFinishLaunchingWithOptions:
方法一样完成工作吗?谢谢!
#import "BRAppDelegate.h"
#import <AssetsLibrary/AssetsLibrary.h>
@implementation BRAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
ALAssetsLibrary *lib = [ALAssetsLibrary new];
[lib enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos usingBlock:^(ALAssetsGroup *group, BOOL *stop){
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
}];
} failureBlock:^(NSError *error){
}];
});
return YES;
}
最奇怪的是,如果我发表评论
[group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop){
}];
不会发生崩溃!
答案 0 :(得分:1)
ALAssetLibrary在主线程的任何线程上运行都不安全。您使用GCDD将其转发到后台,因此在另一个线程中运行。
阅读:http://death-mountain.com/2011/05/alassetslibrary-and-threads/
还要进行竞赛以避免在枚举时改变资产库。这也很糟糕:Has anyone experienced crashes when using ALAssetsLibrary in a background thread?
你在一个块中分配它...一个新的:但是在一个块中它会在块完成后消失,因为没有其他人坚持它。
将lib
的分配移动到主线程中并将其保存为app delegate中的成员变量
这样:
// Override point for customization after application launch.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
ALAssetsLibrary *lib = [ALAssetsLibrary new];
变为:
@implementation AppDelegate {
ALAssetsLibrary *_lib;
}
...
// Override point for customization after application launch.
_lib = [ALAssetsLibrary new];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
答案 1 :(得分:1)
我通过删除我的DerivedData
文件夹清除Xcode的缓存来修复此问题。
rm -rf ~/Library/Developer/Xcode/DerivedData/