OC

Knowledge OS
登录 注册
全部话题 移民 创业 iOS Mac Objective-C Swift Android 招聘 求职

代码请教:无法后台动态更新 UICollectionView

seedante
seedante 发布于 2014年03月22日 | 更新于 2014年04月03日
无人欣赏。

这个问题其实我今天在 stackoverflow 上提问了,但还一直没有人回答,我也没有找到类似的问题。如有违规,请@tinyfool 删帖。 我使用Face++的 iOS离线检测器来检测照片中的人脸,由于是直接检测 iPad 拍摄的图片,检测过程比较长,我希望在后台检测人脸,一旦检测到就更新到屏幕上,以下是我的代码。但检测到的人脸总是在最后一起更新,而不是我希望的那样,检测到一张就更新一张。

#import "FacesetController.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import "FaceppLocalDetector.h"
#import "APIKey+APISecret.h"
#import "FaceppAPI.h"
@interface FacesetController ()
@property (nonatomic, strong) ALAssetsLibrary *photoLibrary;
@property (nonatomic, strong) NSMutableArray *allFaces;
//离线人脸检测器
@property (nonatomic, strong) FaceppLocalDetector *localDetector;
@end
@implementation FacesetController
- (void)viewWillAppear:(BOOL)animated
{
 [super viewWillAppear:animated];
 if (self.photoLibrary == nil) {
 _photoLibrary = [[ALAssetsLibrary alloc] init];
 }
 if (self.allFaces == nil) {
 _allFaces = [[NSMutableArray alloc] init];
 }
 if (self.localDetector == nil) {
 NSDictionary *options = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@NO, @20, FaceppDetectorAccuracyHigh, nil] forKeys:[NSArray arrayWithObjects:FaceppDetectorTracking, FaceppDetectorMinFaceSize, FaceppDetectorAccuracy, nil]];
 _localDetector = [FaceppLocalDetector detectorOfOptions:options andAPIKey:_API_KEY];
 }
 ALAssetsGroupEnumerationResultsBlock assetsEnumerationBlock = ^(ALAsset *result, NSUInteger index, BOOL *stop){
 NSLog(@"Block: assetsEnumerationBlock");
 if (result) {
 @autoreleasepool {
 __autoreleasing ALAssetRepresentation *assetRepresentation = [result defaultRepresentation];
 CGImageRef fullImage = [assetRepresentation fullResolutionImage];
 __autoreleasing UIImage *fullResolutionImage = [UIImage imageWithCGImage:fullImage];
 FaceppLocalResult *detectResult = [_localDetector detectWithImage:fullResolutionImage];
 if (detectResult.faces.count > 0) {
 NSLog(@"Find face in Photo: %@", assetRepresentation.filename);
 for (FaceppLocalFace *face in detectResult.faces) {
 CGImageRef faceCGImage = CGImageCreateWithImageInRect(fullImage, face.bounds);
 __autoreleasing UIImage *faceImage = [UIImage imageWithCGImage:faceCGImage];
 [self.allFaces addObject:faceImage];
 NSIndexPath *indexPath = [NSIndexPath indexPathForRow:self.allFaces.count-1 inSection:0];
 [self.collectionView insertItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
 CGImageRelease(faceCGImage);
 }
 CGImageRelease(fullImage);
 NSLog(@"UPDATE THE MAIN SCREEN!");
 //在主线程中更新屏幕
 dispatch_async(dispatch_get_main_queue(), ^{
 [self.collectionView reloadData];
 });
 }
 }
 }
 };
 // setup our failure view controller in case enumerateGroupsWithTypes fails
 ALAssetsLibraryAccessFailureBlock failureBlock = ^(NSError *error) {
 NSLog(@"Some thing wrong");
 };
 ALAssetsLibraryGroupsEnumerationResultsBlock listGroupBlock = ^(ALAssetsGroup *group, BOOL *stop) {
 ALAssetsFilter *onlyPhotosFilter = [ALAssetsFilter allPhotos];
 [group setAssetsFilter:onlyPhotosFilter];
 [group enumerateAssetsUsingBlock:assetsEnumerationBlock];
 };
 // enumerate only photos
 NSUInteger groupTypes = ALAssetsGroupAlbum | ALAssetsGroupEvent | ALAssetsGroupFaces | ALAssetsGroupSavedPhotos;
 [self.photoLibrary enumerateGroupsWithTypes:groupTypes usingBlock:listGroupBlock failureBlock:failureBlock];
}
- (void)viewDidAppear:(BOOL)animated
{
 [super viewDidAppear:animated];
 NSLog(@"Method: %@", NSStringFromSelector(_cmd));
}
#pragma mark - UICollectionViewDelegate
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
 return self.allFaces.count;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
 return 1;
}
#define kImageViewTag 1
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *cellIdentifier = @"faceCell";
 UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
 if ([self.allFaces count]) {
 UIImageView *faceView = (UIImageView *)[cell viewWithTag:kImageViewTag];
 [faceView setImage:[self.allFaces objectAtIndex:[indexPath row]]];
 }
 return cell;
}
@end
共31条回复
楼长 ·
lionlee 回复于 2014年03月22日

看上去没什么问题啊

2楼 ·
seedante 回复于 2014年03月22日

1楼 @lionlee 我也这么觉得呢,可是所有图片全部都是最后一起出来,而我使用 NSLog来跟踪函数调用,发现每次在 data source 加入新的数据后,(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath也被调用了,可是 UI 上没有反应。

3楼 ·
lionlee 回复于 2014年03月22日

在哪上面测试的?硬件,软件版本,都可能有差异,换个设备再试

4楼 ·
seedante 回复于 2014年03月22日

3楼 @lionlee 我只有个 ipad mini 而且使用的 iOS离线检测器只能在真机上运行。

5楼 ·
lionlee 回复于 2014年03月22日

第二代还是第一代,会不会是和这次的64位调用有关?

6楼 ·
seedante 回复于 2014年03月22日

5楼 @lionlee iPad mini 1代,支持64bit,我觉得应该和这个没什么关系,可能是 GCD 的使用问题,我刚了解这个GCD。

7楼 ·
lionlee 回复于 2014年03月22日

嗯,再找找吧,不过话说即使是dropbox到现在这个版本后台自动备份照片都常常有问题,很多人在说啊,但是他们的工程师到现在都还没找出问题,后台自动刷新方面可能Apple还没成熟,或者是调取过于频繁,总之几分钟之内就会被kill掉,你死的也不冤...

8楼 ·
lionlee 回复于 2014年03月22日

btw ,能看到Diagnostics 吗 ?

9楼 ·
seedante 回复于 2014年03月22日

8楼 @lionlee Diagnostics是调试用的吧 我还不会 暂时用 NSLog 来跟踪。dropbox 应该是有收到新照片的通知来调用进程更新,但我这里只是简单地,主动调用主线程来更新数据而已,除非我的(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath实现得有问题。

10楼 ·
lionlee 回复于 2014年03月22日

http://www.zhihu.com/question/23019630/answer/23369396?utmcampaign=rss&utmmedium=rss&utmsource=rss&utmcontent=title ,推荐你看看,找bug的方法也很重要,毕竟是你自己的东西,good luck

本帖有31个回复,因为您没有注册或者登录本站,所以只能看到本帖的10条回复。如果想看到全部回复,请注册或者登录本站。
登录 或者 注册
[顶 楼]
|
|
[底 楼]
|
|
[首 页]

AltStyle によって変換されたページ (->オリジナル) /