Ios 冻结我的申请

Ios 冻结我的申请,ios,objective-c,iphone,objective-c-blocks,Ios,Objective C,Iphone,Objective C Blocks,我的应用程序有一个小问题 当我使用我的程序块时,应用程序冻结了很长一段时间(将近1分钟),因此我们什么也做不了,所有的滚动/按钮等都不工作 我想优化我的代码,让它工作得更快,用户不必等待1分钟 - (IBAction)exporter:(id)sender { EKEventStore *store = [[EKEventStore alloc] init]; [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL

我的应用程序有一个小问题

当我使用我的程序块时,应用程序冻结了很长一段时间(将近1分钟),因此我们什么也做不了,所有的滚动/按钮等都不工作

我想优化我的代码,让它工作得更快,用户不必等待1分钟

- (IBAction)exporter:(id)sender {
EKEventStore *store = [[EKEventStore alloc] init];
[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
    if (!granted) {
        UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Accès aux calendrier" message:@"L'accès au calendrier est nécessaire pour utiliser cette fonctionnalité" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
        [alert show];
    }


    EKEvent *event = [EKEvent eventWithEventStore:store];

    Variables *objStatutCompte = [Variables getStatutCompte];

    if([objStatutCompte.statutCompte isEqualToString:@"clt"])
    {
        NSString* titreEvent = [NSString stringWithFormat:@"Intervention avec %@", intervenantRecup];
        event.title=titreEvent;

    }
    else if([objStatutCompte.statutCompte isEqualToString:@"slr"])
    {
        NSString* titreEvent = [NSString stringWithFormat:@"Intervention chez %@", clientRecup];
        event.title=titreEvent;
    }

    NSString* lieuEvent = [NSString stringWithFormat:@"%@, %@", adresseClientRecup, villeRecup];


    event.location=lieuEvent;

    NSString* currentDay = [dateRecup substringWithRange:NSMakeRange(0,2)];
    NSInteger jourCourant = [currentDay integerValue];

    NSString* currentMonth = [dateRecup substringWithRange:NSMakeRange(3,2)];
    NSInteger moisCourant = [currentMonth integerValue];

    NSString* currentYear = [dateRecup substringWithRange:NSMakeRange(6,4)];
    NSInteger anneeCourante = [currentYear integerValue];

    NSString* dateDebut = [NSString stringWithFormat:@"%d-%d-%02d %@:00", anneeCourante, moisCourant, jourCourant, heureDebutRecup];
    NSString* dateFin = [NSString stringWithFormat:@"%d-%d-%02d %@:00", anneeCourante, moisCourant, jourCourant, heureFinRecup];

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    [dateFormatter setTimeZone:nil];
    NSDate* dateD = [dateFormatter dateFromString:dateDebut];

    NSDate* dateF = [dateFormatter dateFromString:dateFin];

    event.startDate=dateD;
    event.endDate=dateF;

    NSMutableArray *myAlarmsArray = [[NSMutableArray alloc] init];
    EKAlarm *alarm1 = [EKAlarm alarmWithRelativeOffset:-3600]; // 1 Hour
    [myAlarmsArray addObject:alarm1];

    event.alarms=myAlarmsArray;

    [event setCalendar:[store defaultCalendarForNewEvents]];
    NSError *err = nil;
    [store saveEvent:event span:EKSpanThisEvent commit:YES error:&err];

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Evénement ajouté"
                                                    message:@"L'évenement a bien été ajouté"
                                                   delegate:self
                                          cancelButtonTitle:@"Ok"
                                          otherButtonTitles:nil, nil];
    [alert show];

}];
}

1)用户仪器->时间分析器工具,用于检测应用程序的问题部分: 在Xcode菜单Build->Profile中,选择时间分析器工具,然后开始记录。像往常一样使用应用程序,然后停止录制。在右下角,您需要检查以下设置: “反转调用树”、“隐藏缺少的符号”。然后找出哪个函数占用了大部分CPU时间


2) 根据我的经验,如果您使用某个框架(例如-SDWebImage),为操作阻塞某个线程,然后尝试在此线程中执行某个操作,就会发生这种情况。它也可以发生在主线程中…

requestAccessToEntityType的文档说明:

当用户点击以授予或拒绝访问时,将在任意队列上调用完成处理程序。当用户决定授予或拒绝权限时,您的应用未被阻止

关键在于,
completionHandler
不能在主队列上调用,但所有UI更新必须在主线程上进行

因此,您应该将UI代码分派到主队列:

[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { 
    dispatch_async(dispatch_get_main_queue(), ^{
        // your code here
    });
}];

你有没有发现它在哪一行等待以及为什么等待这么久?@user623396,没有,我不知道如何使用调试工具。顺便说一句,与其寻找CPU使用情况,不如建议使用仪器的“记录等待线程”功能。有时,您可能会遇到一些阻塞,这些阻塞不会表现为CPU使用情况,也可能存在与阻塞调用无关的合法CPU使用情况。我怀疑“记录等待线程”可能会更快地触及问题的核心。我个人怀疑问题在于他从后台队列调用UI方法,但如果不是这样,“记录等待线程”是有用的。