在iOS中,如何在从资产获取图像和视频时应用延迟加载?
我已经从gallery中获取了图像和视频,当视频和图像的数量最少时,它可以正常工作,但当图像和视频的数量较大时,它会阻塞主线程在iOS中,如何在从资产获取图像和视频时应用延迟加载?,ios,Ios,我已经从gallery中获取了图像和视频,当视频和图像的数量最少时,它可以正常工作,但当图像和视频的数量较大时,它会阻塞主线程 -(void)viewDidAppear:(BOOL)animated{ [NSThread sleepForTimeInterval:1]; // call the same method on a background thread dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_D
-(void)viewDidAppear:(BOOL)animated{
[NSThread sleepForTimeInterval:1];
// call the same method on a background thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self getAllVideosAndImages];
});
}
从资产中获取图像和视频
-(void)getAllVideosAndImages{
NSMutableArray *assetGroups = [[NSMutableArray alloc] init];
assetGroups = [[NSMutableArray alloc] init];
library = [[ALAssetsLibrary alloc] init];
NSUInteger groupTypes = ALAssetsGroupAll;
void (^assetEnumerator)
( ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop) {
if(result != nil) {
if([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]||[[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypePhoto]) {
ALAssetRepresentation *rep = [result defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
if (iref) {
//GET DATE
NSDate *myDate = [result valueForProperty:ALAssetPropertyDate];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MMM dd,YYYY"];
NSString *realDateStr = [dateFormatter stringFromDate:myDate];
//GET IMG AND VIDEO
UIImage *largeimage = [UIImage imageWithCGImage:iref];
NSData *webData = UIImagePNGRepresentation(largeimage);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"img%zd.mov",imgName]];
imgName=imgName+1;
[webData writeToFile:localFilePath atomically:YES];
Para_ImageSet *objImgSet=[Para_ImageSet new];
objImgSet.imagePath=localFilePath;
objImgSet.imageDate=realDateStr;
// [yArrayOfAllImges addObject:objImgSet];
if ([[result valueForProperty:ALAssetPropertyType] isEqualToString:ALAssetTypeVideo]) {
objImgSet.is_video=YES;
}
else
{
objImgSet.is_video=NO;
}
if ([tempDate isEqualToString:@""]) {
yArrayOfImagesWithDate=[NSMutableArray new];
[yArrayOfImagesWithDate addObject:objImgSet];
tempDate=realDateStr;
}else
{
//GATE IMAGE COUNT
if ([realDateStr isEqualToString:tempDate]) {
//DO NOTHING
[yArrayOfImagesWithDate addObject:objImgSet];
}
else
{
[yArrayOFNNestedImgs addObject:yArrayOfImagesWithDate];
NSLog(@" ----------ImagesWithDate =%zd, %@",yArrayOfImagesWithDate.count,tempDate);
yArrayOfImagesWithDate=[NSMutableArray new];
[yArrayOfImagesWithDate addObject:objImgSet];
tempDate=realDateStr;
}
}
}
}
}
[self.tableView reloadData];
};
void (^ assetGroupEnumerator) ( ALAssetsGroup *, BOOL *)= ^(ALAssetsGroup *group, BOOL *stop) {
if(group != nil) {
[group enumerateAssetsUsingBlock:assetEnumerator];
[assetGroups addObject:group];
// NSNumber *countObj = [NSNumber numberWithInt:count];
NSLog(@" ----------ImagesWithDate =%zd, %@",yArrayOfImagesWithDate.count,tempDate);
[yArrayOFNNestedImgs addObject:yArrayOfImagesWithDate];
NSLog(@" ----------Count =%zd",yArrayOFNNestedImgs.count);
[NSThread sleepForTimeInterval:10];
// update UI on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}
};
[library enumerateGroupsWithTypes:groupTypes
usingBlock:assetGroupEnumerator
failureBlock:^(NSError *error) {NSLog(@"A problem occurred");}];
}
请建议..提前感谢。
[NSThread sleepForTimeInterval:1]代码>正在阻塞主线程一秒钟。不需要
您可以使用对象为nil的[self-performSelectorInBackground:@selector(getAllVideosAndImages))代码>
另外,首先包装[self.tableView reloadData]代码>输入
dispatch\u async(dispatch\u get\u main\u queue()^{
...
});代码>太为了延迟加载资源,建议采用以下方法:
下载所有资源的URL并将它们存储到您的容器中(数组/对象等)
触发一个在后台队列上运行异步的(仅限post iOS 7)。如果你低于iOS 7,你可以使用-它在iOS 9中已被弃用,所以你最好尽快摆脱它
在后台队列中处理下载的资源-存储音频/图像文件,从NSData创建UIImage,等等
回到主队列,然后用下载的内容更新相关的UI部分。如果是音频/视频,请播放。如果是UIImage,则显示它
这里-整个方法是。即使它很大,也不应该阻塞主线程,这不是你使用GCD将它分配到单独队列中的原因吗?不好,不要使用sleepForTimeInterval:
好,但是如果数据很大,显示时间太长……所以我想执行延迟加载,这就是我使用“sleepForTimeInterval:”的原因,因此在数据未完全加载之前,用户不应被卡住。如果您有任何其他解决方案,请提出建议?一段时间后,它崩溃并出现错误“到assetsd的连接被中断或assetsd死亡”1。您确定没有在非主队列上调用任何与UIView相关的方法吗?2.尝试将AssetGroup和library放入此对象的原子属性中我已经实现了您告诉我的更改…但我面临相同的问题…我观察到,如果我不滚动tableview,它不会崩溃,当我尝试滚动tableview时,它会给我内存警告,然后“与assetsd的连接被中断或assetsd已死亡”…另外,当我提供静态图像而不是资产图像时…它工作正常…与我从资产库检索到的数组计数相同。完成..我使用的是全分辨率图像而不是缩略图..而且问题是未设置原子属性..非常感谢您的帮助