【问题标题】:Xcode iOS app hanging on launch screen "semaphore_wait_trap()"Xcode iOS 应用程序挂在启动屏幕“semaphore_wait_trap()”上
【发布时间】:2016-12-15 07:05:41
【问题描述】:

对不起,我是个菜鸟,不是程序员。我基于模板制作了一个照片编辑应用,并在 Google 搜索、教程等的帮助下对其进行了大量定制。

使用 Xcode 7.3.1、iOS 9.3、更新的 Photosframework 和只有 Objective C。 我已经让应用程序达到了令我满意的程度,但我注意到在第一次启动时应用程序挂起(调试报告 semaphore_wait_trap()。

在 iOS 9.3 中,应用程序无法进入下一步“请求访问照片”警报,唯一的方法是点击主页按钮,然后看到授权访问警报,然后切换回应用程序。然后退出应用程序,重新加载它,然后它可以正常运行。这当然不是理想的用户体验。

我看看我是否暂停调试模式,它挂在:“semaphore_wait_trap()”

我用谷歌搜索并搜索了几天,但找不到让权限警报弹出窗口显示在我的应用窗口顶部的解决方案。

它超出了我的范围。任何想法将不胜感激。

查看显示在警报弹出顶部的启动图像的屏幕截图。

如果您按“主页”按钮,则会出现授予照片访问权限的警报。

应用委托:

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]){
    [application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (locationNotification) {
    // Sets icon badge number to zero
    application.applicationIconBadgeNumber = 0;
}
//  END Local Notification ==========================


return true;

}

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {

// Resets icon's badge number to zero
application.applicationIconBadgeNumber = 0;

}

这是主视图控制器的 sn-p(希望它不会太长,不确定问题出在哪里)

HomeVC.m:

#import "HomeVC.h"
#import "Configs.h"
#import "AAPLGridViewCell2.h"
#import "NSIndexSet+Convenience.h"
#import "UICollectionView+Convenience.h"
#import "AAPLRootListViewController.h"
#import "Configs.h"
#import "ImageEditorTheme.h"
#import "ImageEditorTheme+Private.h"

@import PhotosUI;
@import UIKit;


@interface HomeVC()
<
PHPhotoLibraryChangeObserver,
UICollectionViewDelegateFlowLayout,
UICollectionViewDataSource,
UICollectionViewDelegate
>
@property (nonatomic, strong) NSArray *sectionFetchResults;
@property (nonatomic, strong) NSArray *sectionLocalizedTitles;
@property (nonatomic, strong) PHCachingImageManager *imageManager;
@property CGRect previousPreheatRect;
@property (nonatomic, strong) IBOutlet UICollectionViewFlowLayout *flowLayout;

@property (nonatomic, assign) CGSize lastTargetSize;


@end


@implementation HomeVC

{
    UIActivityIndicatorView *_indicatorView;
}

static NSString * const AllPhotosReuseIdentifier = @"AllPhotosCell";
static NSString * const CollectionCellReuseIdentifier = @"CollectionCell";

static NSString * const CellReuseIdentifier = @"Cell";
static CGSize AssetGridThumbnailSize;


- (void)awakeFromNib {

    self.imageManager = [[PHCachingImageManager alloc] init];
    [self resetCachedAssets];

    [[PHPhotoLibrary sharedPhotoLibrary] registerChangeObserver:self];

}

- (void)dealloc {
    [[PHPhotoLibrary sharedPhotoLibrary] unregisterChangeObserver:self];
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];


    _logoImage.layer.cornerRadius = 30;
    [self loadPhotos];

    [_libraryOutlet addTarget:self action:@selector(touchUp:) forControlEvents:UIControlEventTouchUpInside];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handle_data) name:@"reload_data" object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(hideMenu) name:@"hide_menu" object:nil];

}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    // Begin caching assets in and around collection view's visible rect.
    [self updateCachedAssets];
}

-(void)handle_data {
    //[self.collectionView2 layoutIfNeeded];
    //[self resetCachedAssets];

    [self.collectionView2 reloadData];
    [self updateCachedAssets];
    NSLog(@"did it work?");
}

- (void)viewDidLayoutSubviews
{
    NSInteger section = [self.collectionView2 numberOfSections] - 1;
    NSInteger item = [self.collectionView2 numberOfItemsInSection:section] - 1;
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
    [self.collectionView2 scrollToItemAtIndexPath:indexPath atScrollPosition:(UICollectionViewScrollPositionTop) animated:NO];
    //[self loadPhotos];
}

-(void) loadPhotos {

    PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
    allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];

    PHFetchResult *allPhotos = [PHAsset fetchAssetsWithOptions:allPhotosOptions];


    if (self.assetsFetchResults == nil) {
        self.assetsFetchResults = allPhotos;
    }
}



#pragma mark - PHPhotoLibraryChangeObserver

- (void)photoLibraryDidChange:(PHChange *)changeInstance {
    // Check if there are changes to the assets we are showing.
    PHFetchResultChangeDetails *collectionChanges = [changeInstance changeDetailsForFetchResult:self.assetsFetchResults];
    if (collectionChanges == nil) {
        return;
    }

    /*
     Change notifications may be made on a background queue. Re-dispatch to the
     main queue before acting on the change as we'll be updating the UI.
     */
    dispatch_async(dispatch_get_main_queue(), ^{
        // Get the new fetch result.
        self.assetsFetchResults = [collectionChanges fetchResultAfterChanges];

        UICollectionView *collectionView = self.collectionView;

        if (![collectionChanges hasIncrementalChanges] || [collectionChanges hasMoves]) {
            // Reload the collection view if the incremental diffs are not available
            [collectionView reloadData];

        } else {
            /*
             Tell the collection view to animate insertions and deletions if we
             have incremental diffs.
             */
            [collectionView performBatchUpdates:^{
                NSIndexSet *removedIndexes = [collectionChanges removedIndexes];
                if ([removedIndexes count] > 0) {
                    [collectionView deleteItemsAtIndexPaths:[removedIndexes aapl_indexPathsFromIndexesWithSection:0]];
                }

                NSIndexSet *insertedIndexes = [collectionChanges insertedIndexes];
                if ([insertedIndexes count] > 0) {
                    [collectionView insertItemsAtIndexPaths:[insertedIndexes aapl_indexPathsFromIndexesWithSection:0]];
                }

                NSIndexSet *changedIndexes = [collectionChanges changedIndexes];
                if ([changedIndexes count] > 0) {
                    [collectionView reloadItemsAtIndexPaths:[changedIndexes aapl_indexPathsFromIndexesWithSection:0]];
                }
            } completion:NULL];
        }

        [self resetCachedAssets];
    });
}



#pragma mark - UICollectionViewDataSource

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return self.assetsFetchResults.count;
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath; {

    CGFloat colum = 3.0, spacing = 0.0;
    CGFloat value = floorf((CGRectGetWidth(self.view.bounds) - (colum - 1) * spacing) / colum);

    UICollectionViewFlowLayout *layout  = [[UICollectionViewFlowLayout alloc] init];
    layout.itemSize                     = CGSizeMake(value, value);
    layout.sectionInset                 = UIEdgeInsetsMake(0, 0, 0, 0);
    layout.minimumInteritemSpacing      = spacing;
    layout.minimumLineSpacing           = spacing;


    return CGSizeMake(value, value);
    //return self.collectionView.frame.size;
}


- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    PHAsset *asset = self.assetsFetchResults[indexPath.item];

    // Dequeue an AAPLGridViewCell.
    AAPLGridViewCell2 *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellReuseIdentifier forIndexPath:indexPath];
    cell.representedAssetIdentifier = asset.localIdentifier;


    // Request an image for the asset from the PHCachingImageManager.
    [self.imageManager requestImageForAsset:asset
                                 targetSize:CGSizeMake(130, 130)
                                contentMode:PHImageContentModeAspectFill
                                    options:nil
                              resultHandler:^(UIImage *result, NSDictionary *info) {
                                  // Set the cell's thumbnail image if it's still showing the same asset.
                                  if ([cell.representedAssetIdentifier isEqualToString:asset.localIdentifier]) {
                                      cell.thumbnailImage = result;
                                  }
                              }];
    CGPoint bottomOffset = CGPointMake(-0, self.collectionView.contentSize.height - self.collectionView.bounds.size.height + self.collectionView.contentInset.bottom);
    [self.collectionView setContentOffset:bottomOffset animated:NO];;
        return cell;

}

- (void) collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    // Prepare the options to pass when fetching the live photo.
    PHAsset *asset = self.assetsFetchResults[indexPath.item];
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
    options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    options.networkAccessAllowed = NO;

    dispatch_async(dispatch_get_main_queue(), ^{
        _indicatorView = [ImageEditorTheme indicatorView];
        _indicatorView.center = self.containerView.center;
        [self.containerView addSubview:_indicatorView];
        [_indicatorView startAnimating];
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    PreviewVC *prevVC = (PreviewVC *)[storyboard instantiateViewControllerWithIdentifier:@"PreviewVC"];

    [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:PHImageManagerMaximumSize contentMode:PHImageContentModeAspectFit options:options resultHandler:^(UIImage *result, NSDictionary *info) {


            // Show the UIImageView and use it to display the requested image.
            passedImage = result;

            prevVC.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
            [self presentViewController:prevVC animated:true completion:nil];
        [_indicatorView stopAnimating];
        }];
    });
}


#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    // Update cached assets for the new visible area.
    [self updateCachedAssets];
}

【问题讨论】:

  • 没人有什么建议吗?
  • 您需要提供一些屏幕截图或代码,以便正确理解您的主要问题..
  • 或提供您的应用委托类代码...
  • 我猜你从应用程序委托移动到主视图控制器...你需要将根视图控制器设置为 self.window.rootViewController = HomeViewController;
  • @jayantrawat,不知道你的意思是什么,或者如何实现?

标签: objective-c xcode permissions alert freeze


【解决方案1】:

我设法解决了这个问题。就像删除对“[self resetCachedAssets];”的调用一样简单在“awakeFromNib”中

现在很好用。

【讨论】:

    猜你喜欢
    • 2020-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-26
    相关资源
    最近更新 更多