desbloquear - ¿Cómo saber qué causó el informe de bloqueo de error en el dispositivo IOS?
iphone (1)
¡Cristo ha resucitado (con alegría de la fiesta de Pascua)!
Mientras probaba una aplicación después de la pequeña refactorización de la aplicación, recibí un registro de bloqueo de "Crashlytics". Estaba intentando cambiar el Modelo para evitar la llamada al método de doble sincronización (al mismo tiempo) enviando todas las llamadas siguientes (comenzando desde la segunda llamada) a la cola serie privada. He agregado el siguiente código:
@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;
}
Lo probó usando una llamada recursiva como puede ver. Funcionó. Pero tenga la oportunidad de intentar ejecutar la aplicación en un dispositivo personalmente.
Este método se llama en muy pocos lugares. Principalmente en el único controlador aparente:
- (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)];
}
}
}
He enviado la aplicación a mi jefe de equipo para el check out. Él ha lanzado una aplicación en un dispositivo, pero en un momento (supongo que ha estado funcionando durante un tiempo) se rechazó con un mensaje de error SIGABRT.
El informe Crashlytics regresa:
#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)
Pero como al menos no tengo el archivo dSYM (solo .txt de Crashlytics), no hay una forma obvia de simbolizar el registro de fallos o de entender qué causa el problema. Voy a probarlo en mi dispositivo, pero no estoy seguro si se bloqueará.
Parece que algo sucede con un Threads, pero no estoy seguro de cuál es la pista. ¿Alguien puede aconsejar cómo averiguar el lugar que causa el problema?
Una adición más: hay algunas personas trabajando en un proyecto (soy bastante nuevo) y ni siquiera estoy seguro de que el código que aparece arriba haya activado el error (pero es muy probable) o incluso antes de que mi cambios tuvieron lugar. Acabo de enviar un método pequeño, llamando al método normalmente por primera vez y enviando todas las demás llamadas al mismo tiempo a la cola serie privada. Dado que funcionó recursivamente y este cambio es bastante pequeño y usa solo una cola de serie privada adicional, me confunde, parece demasiado pequeña para una falla real (con el problema de subprocesos en un informe).
Agradecería cualquier consejo.
Parece que debería haber usado los modificadores correctos aquí. Agregar la propiedad "strong" a synchronizationQueue resolvió este problema.
Esta publicación ayudó a encontrar la solución.
¿Qué propiedad debo usar para una cola de envío después de ARC?
Antes de ARC, las colas solían tratarse como un tipo de no objeto, por lo que la "asignación" fue muy útil. Dejarlo vacío funcionaría porque era un modificador predeterminado para los tipos que no son objetos.
No después de que se haya introducido el ARC, las colas se tratan como objetos Objective-c y deberíamos usar "strong" con ellos. Para ser mencionado, el "fuerte" ahora es un atributo de propiedad predeterminado para objetos Objective-c, aún no está seguro de por qué no funcionó en el caso anterior.