7

Reposicionar con una pregunta más concisa y enfocada después de que la pregunta original no fue respondida. También agregando más información sobre el problema después de otro día de investigación:Mostrar una vista es muy lento en CTCallCenter callEventHandler

En mi delegado de la aplicación (didFinishLaunching), configuré un callEventHandler en CTCallCenter. La idea es que cuando un callState cambia, publico una notificación con un userInfo dict que contiene el call.callState. En mi opinión, observo esta notificación, y cuando el dictus de información de usuario contiene un valor de CTCallDisconnected, quiero mostrar una vista.

El problema que estoy teniendo es que el aspecto de desenrrollamiento está tomando, casi constantemente, ~ 7 segundos. Todo lo demás está funcionando bien, y sé esto porque NSLog antes y después del desencriptado, y esos registros aparecen inmediatamente, pero la vista zurcida sigue retrasada durante 7 segundos.

Aquí está mi código:

appDidFinishLaunching:

 
    self.callCenter = [[CTCallCenter alloc] init]; 
    self.callCenter.callEventHandler = ^(CTCall* call) { 
     // anounce that we've had a state change in our call center 
     NSDictionary *dict = [NSDictionary dictionaryWithObject:call.callState forKey:@"callState"]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:@"CTCallStateDidChange" object:self userInfo:dict]; 
    }; 

entonces escucho para esta notificación cuando un usuario pulsa un botón que marca un número de teléfono:

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

Luego, en ctCallStateDidChange :

 
- (void)ctCallStateDidChange:(NSNotification *)notification 
{ 
    NSLog(@"121"); 
    NSString *callInfo = [[notification userInfo] objectForKey:@"callState"]; 
    if ([callInfo isEqualToString:CTCallStateDisconnected]) { 
     NSLog(@"before show"); 
     [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO; 
     NSLog(@"after show"); 
    } 
} 

He rastreado el problema a la condición if en el ejemplo de código anterior:

 
    if ([[userInfo valueForKey:@"userInfo"] valueForKey:@"callState"] == CTCallStateDisconnected) { 

Si sólo tiene que sustituir eso con:

 
if (1 == 1) { 

Entonces la vista aparece inmediatamente!

Lo que pasa es que esas declaraciones NSLog se están registrando inmediatamente, pero la vista es quedando rezagada. ¿Cómo podría esa condición causar que solo una parte de su bloque se ejecute inmediatamente, y el resto espere ~ 7 segundos?

Gracias!

+0

Proceso de ocultar/revelar la vista es muy rápido. El problema es con el contenido de su vista y su super visión. ¿Has intentado perfilar el caso con instrumentos? Código postal donde configura la vista que se ocultará y verá que se revelará después de ocultarse. – Zapko

+0

Gracias. Acabo de actualizar mi publicación original. La imagen en la vista es de 4 KB, así que no creo que sea un problema. Solo traté de dejar la imagen, y todavía tengo el retraso. No muy familiarizado con los instrumentos. Solo he mirado realmente las pérdidas de memoria a través de esa herramienta, por lo que no estoy muy seguro de cómo inspeccionaría lo que sucede aquí detrás de escena. – djibouti33

+0

Utilice el perfil de tiempo, le mostrará la pila de llamadas en todo momento y el tiempo que funcionó cada función. Seguramente lo ayudará – Zapko

Respuesta

10

trate de cambiar su código para esto:

- (void)ctCallStateDidChange:(NSNotification *)notification 
{ 
    NSLog(@"121"); 
    NSString *callInfo = [[notification userInfo] objectForKey:@"callState"]; 
    if ([callInfo isEqualToString:CTCallStateDisconnected]) { 
     NSLog(@"before show"); 
     [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO; 
     NSLog(@"after show"); 
    } 
} 

Nota:

  • El parámetro es un NSNotification, no un NSDictionary
  • no me comparar cadenas con ==
  • No hay necesidad lanzar la vista para cambiar la propiedad hidden
  • Uso
  • NO en lugar de false

actualización: ¿Tienes una idea: ¿Podrías tratar el siguiente, por favor, entre los NSLog s?

dispatch_async(dispatch_get_main_queue(), ^{ 
    [self.view viewWithTag:kNONEMERGENCYCALLSAVEDTOLOG_TAG].hidden = NO; 
}); 

lectura del documento CTCallCenter, parece que el callEventHandler se despacha en "la prioridad predeterminada de cola mundial de despacho", que no es la cola principal donde pasa todo el material de interfaz de usuario.

+0

Gracias Thomas. Si bien todas sus sugerencias son apropiadas y bien recibidas (incluso actualicé mi pregunta para usar su muestra de código), sigo teniendo exactamente el mismo problema. 7 segundos antes de que aparezca la vista. El problema no es que no pueda satisfacer la condición (incluso mi código que editó satisfacía la condición IF), es que sí lo está, los dos registros de NSLog, pero la vista no aparece durante 7 segundos. Además, un poco fuera de tema, pero ¿cuándo es necesario emitir y cuándo puedes dejarlo? – djibouti33

+0

Debe realizar el envío a su subclase si desea acceder a una de sus propiedades o métodos. 'hidden' es una propiedad de' UIView', por lo que no es necesario lanzarlo aquí. –

+0

Además, recuerde @Thomas Müller, que si cambio la condición IF a: if (1 == 1), también (obviamente) está satisfecho, pero todo funciona correctamente. Los primeros registros de registro, la vista aparece inmediatamente y luego el segundo registro registra. Algo sobre esa condición específica está causando un retraso en la aparición de la vista. – djibouti33

0

Parece que no hay problema con su código oculto. Si yo fuera usted, comentaría todo el código después de que termine la llamada y los descomentaré uno por uno para ver cuál es el problema.

+0

gracias, pero eso no pareció funcionar. en mi controlador de devolución de llamadas, lo descomente todo después de mostrar la vista, y todavía tiene un retraso de 7 segundos. – djibouti33

0

Hm ... intente llamar al [yourViewController.view setNeedsDisplay] después de cambiar la propiedad oculta. O bien, evite los métodos ocultos, use los métodos alpha o addSubview: y removeFromSuperview.

+0

gracias por todas sus sugerencias @Zapko. Acabo de descubrir que si elimino las condiciones que prueban para appDelegate.userInitiatedCall.callState, todo aparece inmediatamente, como se desee. No estoy seguro de por qué revisar un ivar en el delegado de la aplicación tarda tanto. ¿Algunas ideas? – djibouti33

+0

Debe tener en cuenta que cuando escribe 'appDelegate.userInitiatedCall.callState == something' no está verificando el iVar que está llamando a 2 métodos' [[appDelegate userInitiatedCall] callState] '. El tiempo de ejecución de estos métodos depende de su complejidad. Por ejemplo, si acaba de sintetizarlos pero no los configuró _nonatomic_ tomaría mucho más tiempo para realizarlos que _nonatomic_ ones. Si tiene varias llamadas para alguna propiedad en un método, es razonable hacer var local, en su caso 'Call * initedCall = appDelegate.userInitiatedCall'. – Zapko

+0

Compruebe declaraciones y, si es posible, implementaciones de todas las propiedades que usa varias veces en su ifs. Si habrá algunos complejos o seguros para hilos (atómicos), tendría sentido. – Zapko

0

djibouti33,

Cuando se pone esta frase para escuchar cuando un usuario pulsa un botón que marca un número de teléfono? WillResignActive en la función?

esta frase -> [[NSNotificationCenter defaultCenter] addObserver: nombre @selector (ctCallStateDidChange :):: auto selector @ "CTCallStateDidChange" objeto: nil];

Gracias por su tiempo,

Willy.

+0

El botón que un usuario toca para realizar una llamada tiene un objetivo/acción asignado (handleDialTap :).Dentro de handleDialTap, hago algunas cosas, una de las cuales es llamar a otro método llamado dialOut :. Inside dialOut: es donde empiezo a escuchar la notificación ctCallStateDidChange. Espero que ayude. – djibouti33