Le Christ est ressuscité (avec une joie de la fête de Pâques)!
Lors du test d'une application après le refactoring d'une petite application, j'ai reçu un journal de panne "Crashlytics". Essayait de changer le modèle pour éviter l'appel de la méthode de double synchronisation (en même temps) en envoyant tous les prochains appels (à partir du deuxième appel) vers la file d'attente série privée. J'ai ajouté le code suivant:Comment savoir ce qui a causé un rapport d'erreur sur un périphérique IOS?
@interface SynchronizationModel()
@property (nonatomic) dispatch_queue_t synchronizationQueue;
@end
@implementation SynchronizationModel
BOOL isSynchronizationNotCalled = YES;
#pragma mark - Synchronization
+ (dispatch_queue_t)synchronizationQueue {
static dispatch_queue_t queue;
static dispatch_once_t onceToken;
const char *queueID = "com.app.synchronizationModel.queue";
dispatch_once(&onceToken, ^{
queue = dispatch_queue_create(queueID, DISPATCH_QUEUE_SERIAL);
});
return queue;
}
+ (void)sychronizeOfflineObjects {
if (isSynchronizationNotCalled) {
NSLog(@"%d synchronization without a queue, flag notCalled =", isSynchronizationNotCalled);
isSynchronizationNotCalled = NO;
[self synchronizeOfflineObjectsNonAsynchronous];
} else {
NSLog(@"%d synchronization inside of a queue, flag notCalled =", isSynchronizationNotCalled);
isSynchronizationNotCalled = NO;
__weak typeof(self)weakSelf = self;
dispatch_async(self.synchronizationQueue, ^{
__strong typeof(weakSelf)strongSelf = weakSelf;
[strongSelf synchronizeOfflineObjectsNonAsynchronous];
});
}
// [self sychronizeOfflineObjects]; - uncomment for recursive test
isSynchronizationNotCalled = YES;
}
Testé en utilisant un appel récursif comme vous pouvez le voir. Cela a fonctionné. Mais avoir la possibilité d'essayer de lancer l'application sur un appareil personnellement.
Cette méthode est appelée dans les très rares endroits. Principalement dans le contrôleur apparent:
- (IBAction)buttonWasTapped:(id)sender {
if(self.buttonImage.layer.animationKeys.count == 0){
[self synchronizationMethod];
}
}
- (void)synchronizationMethod {
NSLog(@"startWorkWithServer - originally here is some code but it works perfect");
[SynchronzationModel sychronizeOfflineObjects];
} else {
[self startAnimation];
[self performSelector:@selector(delayStop) withObject:nil afterDelay:2.0];
if([webConnectionAllowed isEqualToString:@"NotAllowed"]){
[self showAlertWithTitle:nil message:NSLocalizedString(@"Connection is allowed", nil)];
}
}
}
J'ai envoyé l'application à mon chef d'équipe pour le check-out. Il a lancé une application sur un périphérique, mais en un instant (supposons que cela fonctionne depuis un certain temps), il a été désactivé avec un message d'erreur SIGABRT.
rapport Crashlytics retourne:
#0. Crashed: com.twitter.crashlytics.ios.exception
0 App 0x18751d CLSProcessRecordAllThreads + 820509
1 App 0x18751d CLSProcessRecordAllThreads + 820509
2 App 0x187415 CLSProcessRecordAllThreads + 820245
3 App 0x17b34f CLSHandler + 770895
4 App 0x185dfb __CLSExceptionRecord_block_invoke + 814587
5 libdispatch.dylib 0x1c942083 _dispatch_client_callout + 22
6 libdispatch.dylib 0x1c94e33b _dispatch_barrier_sync_f_invoke + 50
7 App 0x1857fd CLSExceptionRecord + 813053
8 App 0x185625 CLSExceptionRecordNSException + 812581
9 App 0x18513b CLSTerminateHandler() + 811323
10 libc++abi.dylib 0x1c4f393f std::__terminate(void (*)()) + 78
11 libc++abi.dylib 0x1c4f3443 __cxa_rethrow + 90
12 libobjc.A.dylib 0x1c4ff1bb objc_exception_rethrow + 42
13 CoreFoundation 0x1d1a55a1 CFRunLoopRunSpecific + 596
14 CoreFoundation 0x1d1a5341 CFRunLoopRunInMode + 104
15 GraphicsServices 0x1e97cbfd GSEventRunModal + 156
16 UIKit 0x223b3e27 -[UIApplication _run] + 574
17 UIKit 0x223ae551 UIApplicationMain + 150
18 App 0x148daf main (main.m:14)
19 libdispatch.dylib 0x1c96f50b (Missing)
Mais depuis au moins je n'ai pas le fichier dSYM (seulement txt de Crashlytics) s `aucune manière évidente pour moi de symbolicate le journal d'accident ou de comprendre les causes le problème. Je vais le tester sur mon appareil, mais je ne suis pas sûr qu'il va tomber en panne.
Il semble que quelque chose se passe avec un Threads, mais je ne suis pas sûr exactement ce qu'est l'indice. Quelqu'un peut-il conseiller comment déterminer l'emplacement causant le problème.
Un ajout de plus: il y a quelques personnes qui travaillent sur un projet (je suis assez nouveau) et je ne suis même pas sûr que le code placé dessus a déclenché l'erreur (mais très probablement) était même avant que mes changements ont eu lieu. J'ai juste aded une petite méthode, appelant la méthode normalement pour la 1ère fois et envoyant tous les appels de repos se produit dans la même heure à la file d'attente sérielle privée. Comme cela a fonctionné de manière récursive et qu'il s'agit d'un petit changement et qu'il n'utilise qu'une seule file d'attente série privée supplémentaire, il me semble un peu trop petit pour un crash réel (avec le problème Threads dans un rapport).
Apprécierait n'importe quel conseil.
Vous n'avez pas fourni de définition pour: 'synchronizeOfflineObjectsNonAsynchronous' – Brandon
Oui, j'imagine que ce modèle fonctionnait correctement avant que j'apporte les modifications par-dessus, donc j'ai ajouté seulement du code qui a été fait par moi-même. Et cela rendrait également ce post plus grand.Mais si vous pensez que cela pourrait clarifier la situation, je pourrais ajouter plus de code? – Alexander
+ (void) synchronizeOfflineObjectsNonAsynchronous {[self changeUser]; if ([AppGroups allObjects] .count == 0) {[[OfflineChangesModel sharedInstance] terminé]; revenir; } if (! mainGroupId) {[self synchronisationForNoMainGroupID]; } else {[self synchronisationForMainGroupID]; }}. Je pourrais ajouter plus de code pour le synchronizationForNoMainGroupID et le synchronizationForMainGroupID si c'est nécessaire mais cela a fonctionné bien avant que j'aie fait les changements écrits ci-dessus. – Alexander