users standard property non how attempt ios objective-c uikit nsuserdefaults property-list

ios - standard - Cientos de accesos a "InputModeProperties.plist" están retrasados en mi juego(iPhone)



userdefaults standard swift 4 (6)

Tengo un problema extraño con una corrección de errores para Tiny Wings. En mi juego uso algo como:

NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults setFloat:musicVolume forKey:@"musicVolume"];

para guardar algunas preferencias y la tabla de mejores puntuaciones. Al final del juego, cuando aparece la pantalla de cambio de juego, el juego guarda las puntuaciones más altas en los valores estándar del usuario. Funciona muy bien hasta que el juego muestra un UIAlertView como este:

UIAlertView *alert = [[UIAlertView alloc] init]; [alert setTitle:@"Get ready!"]; [alert setDelegate:self]; [alert addButtonWithTitle:@"Ok"]; [alert show]; [alert release];

Después de que AlertView desapareciera cada vez que el juego guardaba algo para el estándar UssDefaults, el juego se demora un poco (en algunos dispositivos durante varios segundos). Esto también sucede después de que el juego usó un UITextField para ingresar el nombre del jugador. No hay ningún retraso en el juego antes de que se use uno de los dos elementos UIKit, pero después de su uso, el juego se retrasa hasta que reinicie la aplicación. He analizado el problema con las herramientas de rendimiento y el instrumento "Actividad de E / S" muestra que hay cientos de accesos de "apertura - lectura - cierre" a la

/System/Library/Frameworks/UIKit.framework/InputModeProperties.plist

lo que provoca los retrasos.

Totalmente no tengo ni idea de qué hacer. ¿Algunas ideas?

Editar:
hay un hilo en el foro de desarrolladores de Apple http://devforums.apple.com/message/424374#424374 donde alguien tiene un problema igual y parece que solo aparece con iOS 4.3. Lo he probado y los retrasos solo ocurren en mis dispositivos 4.3 (no en un iPod Touch 3.1 y en un iPad 4.2).


No se recomienda usar UIKit y OpenGL juntos. No creo que esta visión sea tanto el problema como el concepto de mezclar los dos. Recomiendo encarecidamente nixing esa alerta y, en cambio, muestre una superposición personalizada, para que pueda lograr dos cosas:

  1. Haz que la alerta "Prepárate" coincida con los gráficos del juego.
  2. Evita este problema por completo.

He visto un rendimiento lento con la versión actualmente lanzada en la App Store, al reanudar el juego en un iPod touch de segunda generación.

Si desea mantener esos elementos tal como están, esta publicación del Foro de desarrolladores de Apple sugiere ejecutar la sincronización en un hilo separado. Siguiendo con eso, sugeriría estos pasos:

  1. Como se sugirió en otros, mantenga una referencia a NSUserDefaults en algún lugar. (Por lo general, solo hago algo como esto: #define kSettings [NSUserDefaults standardUserDefaults] . Por supuesto, debes invocarlo una vez para crear una instancia del singleton).

  2. Ejecute la llamada de synchronize en un segundo hilo (según la publicación del Foro de desarrolladores de Apple).

  3. Vea si puede synchronize llamadas en otro momento que willResignActive sea willResignActive . El problema parece un poco peor cuando llamas a sincronizar desde ese método.

Felicidades por el juego.


Ok, mirando alrededor parece que InputModeProperties.plist es solo una lista de teclados de hardware y software.

Al mirar el hilo del foro que publicó este problema, parece ser que esencialmente después de cargar un objeto UITextField o UIAlertView (que incluye UITextInputTraits.h entre otros) siempre que intente guardar los valores predeterminados del usuario, existe un bucle inexplicable de un archivo de definiciones de teclados. Esto solo ocurre en iOS 4.3.

Me parece terriblemente un error en UIKit y supongo que de repente UIKit está guardando un montón de cosas sin ningún propósito real. Si este es el caso, puede ser difícil hacer algo al respecto, aunque podría evitar estos elementos (no está mal para la alerta, pero el campo de texto será más complicado) o podría cambiar a los datos centrales. Alternativamente, puede hacer un diccionario mutable para todas sus opciones y guardarlo en los valores predeterminados del usuario cuando la aplicación se cierra y le importa menos una pausa. O, simplemente llevar a cabo una actualización.

Buena suerte (me encanta el juego por cierto)


Probablemente guarda cada uno su opción como una transacción separada. No estoy seguro. Puede intentar usar su propia clase de DataStorage de singleton con NSMutableDictonairy como almacenamiento de datos. Y sincronícelo con NSUserDefaults en applicationDidEnterBackground: y applicationWillTerminate: O incluso si no usó la configuración del sistema con sus NSUserDefaults, podría guardar este NSMutableDictonairy de la siguiente manera:

tempData = [NSMutableData data]; archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:tempData]; [archiver encodeObject:mutableDict forKey:@"data"]; [archiver finishEncoding]; result = [tempData writeToFile:archivePath atomically:YES]; [archiver release];

ps pulgar hacia arriba para pequeñas alas. ;)


Solo un tiro en la oscuridad al mirar la diferencia de 4.3.

Quizás una combinación de lo nuevo.

- (BOOL)disablesAutomaticKeyboardDismissal

en UIViewController y UIModalPresentationFormSheet (donde este valor predeterminado es YES) está causando algún tipo de bucle en su código.


Suponiendo que ejecute un método para mostrar la vista de alerta, ¿ha intentado lo siguiente?

[self performSelector:@selector(displayAlert) withObject:nil afterDelay:0.5]; - (void)displayAlert { UIAlertView *alert = [[UIAlertView alloc] init]; [alert setTitle:@"Get ready!"]; [alert setDelegate:self]; [alert addButtonWithTitle:@"Ok"]; [alert show]; [alert release]; }

La razón por la que pregunto es que a menudo he experimentado un comportamiento extraño al intentar ejecutar un método inmediatamente después de sincronizar NSUserDefaults . De lo contrario, realmente necesitaríamos ver un poco más de código para determinar qué está sucediendo.


EDITAR

Una solución de error decente :

Versión corta: solo demora las llamadas de activación de errores hasta que el usuario no esté molesto.

Versión larga:

Ya que creo que el problema proviene de la [NSUserDefaults standardUserDefaults] , que desencadena ese bucle de carga de plist sucio DESPUÉS de alguna acción solicitando diseños de teclado (como una UIAlert ) ...

Sugeriría llamar a [NSUserDefaults standardUserDefaults] solo una vez al cargar la aplicación ( ANTES de cualquier llamada que cause un error) , y mantener la referencia devuelta en una clase singleton durante todo el ciclo de vida de la aplicación. No creo que la huella de memoria sea enorme ... (Estoy haciendo esto en varias aplicaciones sin ningún problema). En el peor de los casos, la carga plist * 100 se haría solo una vez en la carga de la aplicación, y no durante el juego.

Si el problema proviene de las [userDefaults setXxxx:...] , la misma solución alternativa, puede guardar los valores para guardar en la memoria y configurarlos más tarde en userDefaults , como antes de sincronizarlos ... Pero a riesgo de perder información si todo sale mal, como un choque. Personalmente prefiero sync después de cada set para garantizar la integridad de los datos ...

ENDOFEDIT

La respuesta corta: error de iOS4.3, muy pocas posibilidades de encontrar una solución ... informe de errores y espere la próxima actualización de iOS ... WWDC en 2 semanas ... 1 ~ 2 meses.

El largo:

Después de ver el ensamble de UIKit, aquí están mis conjeturas:

  • InputModeProperties.plist contiene una lista de todos los diseños de teclados por ubicación.
  • UIKit usa esto para varias cosas, como cuando se muestra un teclado, para determinar la disposición de los teclados disponibles. (Locales ...)
  • Una cosa es interesante, podemos encontrar algunas de sus informaciones en NSUserDefaults :

    NSLog(@"%@", [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]); ==> { AppleKeyboards = ( // I have two keyboard in preferences "fr_FR@hw=French;sw=AZERTY", // french first "en_US@hw=US;sw=QWERTY" // english second ); ...

  • Pero estas informaciones no se almacenan en las preferencias de las aplicaciones, a diferencia de su puntaje. ( NSGlobalDomain , o más probablemente dominios separados para cada uno de los idiomas preferidos del usuario )
  • Por lo tanto, no me sorprendería que exista un conflicto (error) en UIKit + NSUserDefaults que provoque ese sucio bucle de carga de errores.
  • Alrededor de 100 llamadas que dices? Eso es algo así como el número de locale / layouts en el plist!

Cuando no hay ningún teclado disponible en NSUserDefaults ... (como después de sincronizar, imaginemos un error al hacer esto) ... UIKit podría probar todos los teclados disponibles para determinar el usuario, analizando directamente este 4.4K plist cien veces ... Como cuando se muestra un UIAlertView ... después de un NSUSerDefault sync / change.

¿Quién sabe? La gente de Apple que tiene el código fuente :)

No me sorprendería ir a las preferencias para configurar un teclado que no sea el predeterminado en EE. UU. Y luego volver a EE. UU. Resolvería el problema. Inútil en su caso, pero confirmaría el problema. Visto por otro error de 4.3 ...

Como dijeron otras personas, no usar NSUserDefaults sino una simple lista personalizada en / Documentos podría ser una solución (in) decente.

¡Gran trabajo en Tiny Wings! :)