下面的方法被放在默认的全局队列中,以便从设备获取一些照片。如果系统版本高于iOS 8,则使用Photos
框架,否则使用ALAssetLibrary
。
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self getPhotos:^(NSArray *photos) {
dispatch_semaphore_signal(sema);
}];
}
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC));
dispatch_semaphore_wait(sema, timeout);
- (void)getPhotos:(MyCallBack)callback {
Class PHPhotoLibrary_class = NSClassFromString(@"PHPhotoLibrary");
if (PHPhotoLibrary_class) {
PHAuthorizationStatus status = [PHPhotoLibrary authorizationStatus];
if (status != PHAuthorizationStatusAuthorized)
{
return;
}
PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
}
}
应用程序崩溃,在64位设备上,如iPhone 5S和更新的型号,堆栈跟踪如下。
Exception Type: SIGTRAP
Exception Codes: TRAP_BRKPT at 0x190c41b60
Crashed Thread: 25
Thread 25 Crashed:
0 PhotoLibraryServices 0x0000000190c41b60 +[PLModelMigrator _validateCurrentModelVersionFailedWithNoVersionFromServer] :444 (in PhotoLibraryServices)
1 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
2 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
3 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
4 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
5 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
6 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
7 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
8 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
9 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
10 PhotoLibraryServices 0x0000000190c41ef8 +[PLModelMigrator _validateCurrentModelVersionAttempt:] :316 (in PhotoLibraryServices)
11 PhotoLibraryServices 0x0000000190c43688 +[PLModelMigrator createDatabase] :508 (in PhotoLibraryServices)
12 PhotoLibraryServices 0x0000000190b7c1cc -[PLPhotoLibrary loadDatabase:] :808 (in PhotoLibraryServices)
13 PhotoLibraryServices 0x0000000190b71f70 -[PLPhotoLibrary initWithTransientContext:name:] :560 (in PhotoLibraryServices)
14 Photos 0x0000000191722418 ___45-[PHPhotoLibrary backgroundQueuePhotoLibrary]_block_invoke :60 (in Photos)
15 libdispatch.dylib 0x0000000184bb21bc __dispatch_client_callout :16 (in libdispatch.dylib)
16 libdispatch.dylib 0x0000000184bb2fb0 _dispatch_once_f :56 (in libdispatch.dylib)
17 Photos 0x00000001917223d4 -[PHPhotoLibrary backgroundQueuePhotoLibrary] :156 (in Photos)
18 Photos 0x0000000191722604 -[PHPhotoLibrary photoLibraryForCurrentQueueQoS] :80 (in Photos)
19 Photos 0x0000000191722578 -[PHPhotoLibrary managedObjectContextForCurrentQueueQoS] :24 (in Photos)
20 Photos 0x00000001917611bc -[PHQuery _createFetchRequestIncludingBasePredicate:] :140 (in Photos)
21 Photos 0x0000000191761c5c -[PHQuery fetchRequest] :52 (in Photos)
22 Photos 0x0000000191783988 -[PHFetchResult initWithQuery:oids:registerIfNeeded:usingManagedObjectContext:] :376 (in Photos)
23 Photos 0x0000000191783c2c -[PHFetchResult initWithQuery:] :100 (in Photos)
24 Photos 0x0000000191763b5c -[PHQuery executeQuery] :52 (in Photos)
25 Photos 0x00000001916c2998 ___67+[PHAssetCollection fetchAssetCollectionsWithType:subtype:options:]_block_invoke :72 (in Photos)
26 Photos 0x000000019175fe48 +[PHObject authorizationAwareFetchResultWithOptions:fetchBlock:] :88 (in Photos)
27 Photos 0x00000001916c2944 +[PHAssetCollection fetchAssetCollectionsWithType:subtype:options:] :84 (in Photos)
通常在32位设备上,如iPhone5、iPhone4S,崩溃报告如下:
Exception Type: SIGABRT
Exception Codes: #0 at 0x1b448ad4
Crashed Thread: 1
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException' reason: 'CoreData: Cannot load NSManagedObjectModel. nil is an illegal URL parameter'
Last Exception Backtrace:
0 CoreFoundation 0x1bca0df7 ___exceptionPreprocess :131 (in CoreFoundation)
1 libobjc.A.dylib 0x1af03077 _objc_exception_throw :39 (in libobjc.A.dylib)
2 CoreData 0x1dc190c5 +[NSManagedObjectContext initialize] :1 (in CoreData)
3 PhotoLibraryServices 0x256a45d5 ___44+[PLManagedObjectContext managedObjectModel]_block_invoke :89 (in PhotoLibraryServices)
4 AssetsLibraryServices 0x24fc527d ___pl_dispatch_once_block_invoke :19 (in AssetsLibraryServices)
5 libdispatch.dylib 0x1b346083 __dispatch_client_callout :23 (in libdispatch.dylib)
6 libdispatch.dylib 0x1b346c65 _dispatch_once_f :43 (in libdispatch.dylib)
7 AssetsLibraryServices 0x24fc5267 _pl_dispatch_once :77 (in AssetsLibraryServices)
8 PhotoLibraryServices 0x256a456d +[PLManagedObjectContext managedObjectModel] :73 (in PhotoLibraryServices)
9 Photos 0x26139475 +[PHQuery _relationshipForFetchType:predicate:] :257 (in Photos)
10 Photos 0x2613a4cd -[PHQuery collectionFetchType] :85 (in Photos)
11 Photos 0x261392b1 -[PHQuery copyWithZone:] :303 (in Photos)
12 Photos 0x26158239 -[PHFetchResult initWithQuery:oids:registerIfNeeded:usingManagedObjectContext:] :125 (in Photos)
13 Photos 0x26158567 -[PHFetchResult initWithQuery:] :81 (in Photos)
14 Photos 0x2613c0cb -[PHQuery executeQuery] :53 (in Photos)
15 Photos 0x260aaf4f ___67+[PHAssetCollection fetchAssetCollectionsWithType:subtype:options:]_block_invoke :73 (in Photos)
16 Photos 0x2613898d +[PHObject authorizationAwareFetchResultWithOptions:fetchBlock:] :63 (in Photos)
17 Photos 0x260aaf03 +[PHAssetCollection fetchAssetCollectionsWithType:subtype:options:] :97 (in Photos)
这看起来像是一个核心数据错误,我也不明白为什么AssetsLibraryServices
和PhotoLibraryServices
都存在于上一个崩溃报告中。我尝试了许多方法,但无法重现崩溃,任何帮助都是感激的。
发布于 2017-05-22 06:12:19
这里遗漏了一些东西,主要是您对getPhotos
的调用的上下文,我注意到您从未使用smartAlbums
或回调做任何事情。也许你只是没有把它包括进来,因为你认为它不相关。
无论如何,我创建了一个新项目(包括核心数据),下面是我所做的一切。工作时不会崩溃:
1)将NSPhotoLibraryUsageDescription
添加到plist
2)在AppDelegate.h
中添加了如下内容
#import <Photos/Photos.h>
typedef void (^MyCallBack)(NSArray *photos);
3)将AppDelegate.m
中didFinishLaunchingWithOptions
的默认实现替换为:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusAuthorized) {
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self getPhotos:^(NSArray *photos) {
dispatch_semaphore_signal(sema);
}];
});
}
}];
dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC));
dispatch_semaphore_wait(sema, timeout);
return YES;
}
- (void)getPhotos:(MyCallBack)callback {
Class PHPhotoLibrary_class = NSClassFromString(@"PHPhotoLibrary");
if (PHPhotoLibrary_class) {
PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
NSMutableArray *photos = [[NSMutableArray alloc] init];
int i = 0;
for (PHAssetCollection *assetCollection in smartAlbums)
{
i++;
PHFetchResult *smartAlbum = [PHAsset fetchAssetsInAssetCollection:assetCollection options:nil];
int j = 0;
for (PHAsset *asset in smartAlbum)
{
j++;
[[PHImageManager defaultManager]
requestImageDataForAsset:asset
options:nil
resultHandler:^void(NSData * _Nullable imageData, NSString * _Nullable dataUTI, UIImageOrientation orientation, NSDictionary * _Nullable info) {
[photos addObject:[UIImage imageWithData:imageData]];
if (i == [smartAlbums count] && j == [smartAlbum count]) {
callback([NSArray arrayWithArray:photos]);
}
}];
if (i == [smartAlbums count] && j == [smartAlbum count]) {
return;
}
}
}
}
}
发布于 2017-05-28 22:31:13
根据我的经验,没有必要在子线程中使用getPhotos
或fetchAssetCollectionsWithType
。试一试吧。
https://stackoverflow.com/questions/44074368
复制相似问题