1

我一直在努力解决这个错误时间,最后我深入研究了这段代码。此代码在您“运行”应用程序时运行良好,但在“测试”时会导致应用程序崩溃。我用谷歌搜索并发现了这个问题:

在设备上运行 OCUnit 应用程序测试套件时偶尔出现错误

但是该解决方案对我不起作用;-(

我是一名新手 iOS 开发人员,所以我不确定这段代码是否做坏事。谁能告诉我:

  1. 可以像方法中那样做工作application:didFinishLaunchingWithOptions:吗?
  2. 为什么这段代码会抛出错误?

谢谢!

#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){

}];

不会发生崩溃!

4

2 回答 2

1

我通过删除我的DerivedData文件夹来清除 Xcode 的缓存来解决这个问题。

rm -rf ~/Library/Developer/Xcode/DerivedData/
于 2014-01-31T11:19:16.527 回答
1

ALAssetLibrary 在除主线程之外的任何线程上运行都不安全。您使用 GCDD 将其调度到后台,因此在另一个线程中运行。

阅读:http ://death-mountain.com/2011/05/alassetslibrary-and-threads/

在枚举资产库时也要竞相避免改变资产库。那也很糟糕:有没有人在后台线程中使用 ALAssetsLibrary 时遇到过崩溃?


但主要问题是你如何使用我认为的库......

你在一个块中分配它..一个新的:但是在一个块中,所以它在块完成后消失,因为没有其他人在持有它。

将分配移动lib到主线程并将其保存为应用程序委托中的成员变量

所以:

// 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) {
于 2013-06-26T18:02:08.350 回答