videos tamaño recortar para imagen gratis editar como app activo activar iphone objective-c cocoa cocoa-touch ios

tamaño - nfc iphone se



¿Cuáles son las mejores prácticas que utiliza al escribir Objective-C y Cocoa? (30)

Evitar autorelease

Debido a que normalmente (1) no tiene control directo sobre su vida útil, los objetos lanzados automáticamente pueden persistir por un tiempo comparativamente largo y aumentar innecesariamente la huella de memoria de su aplicación. Si bien en el escritorio esto puede tener poca importancia, en plataformas más restringidas puede ser un problema importante. Por lo tanto, en todas las plataformas, y especialmente en las plataformas más restringidas, se considera la mejor práctica para evitar el uso de métodos que conduzcan a la publicación automática de objetos y, en su lugar, se recomienda utilizar el patrón alloc / init.

Así, en lugar de:

aVariable = [AClass convenienceMethod];

donde sea posible, deberías usar:

aVariable = [[AClass alloc] init]; // do things with aVariable [aVariable release];

Cuando está escribiendo sus propios métodos que devuelven un objeto recién creado, puede aprovechar la convención de nomenclatura de Cocoa para señalar al receptor que debe liberarse al añadir el nombre del método con "nuevo".

Así, en lugar de:

- (MyClass *)convenienceMethod { MyClass *instance = [[[self alloc] init] autorelease]; // configure instance return instance; }

usted podría escribir:

- (MyClass *)newInstance { MyClass *instance = [[self alloc] init]; // configure instance return instance; }

Dado que el nombre del método comienza con "nuevo", los consumidores de su API saben que son responsables de liberar el objeto recibido (consulte, por ejemplo, el método newObject de newObject ).

(1) Puede tomar el control utilizando sus propios grupos locales de autorelease. Para más sobre esto, vea Grupos de Autorelease .

Sé sobre el HIG (¡que es bastante útil!), Pero qué prácticas de programación utiliza al escribir Objective-C, y más específicamente cuando usa Cocoa (o CocoaTouch).


IBOutlets

Históricamente, la gestión de memoria de las salidas ha sido deficiente. La mejor práctica actual es declarar puntos de venta como propiedades:

@interface MyClass :NSObject { NSTextField *textField; } @property (nonatomic, retain) IBOutlet NSTextField *textField; @end

El uso de propiedades hace que la semántica de administración de memoria sea clara; también proporciona un patrón consistente si utiliza la síntesis de variables de instancia.


No use cadenas desconocidas como cadenas de formato

Cuando los métodos o funciones toman un argumento de cadena de formato, debe asegurarse de que tiene control sobre el contenido de la cadena de formato.

Por ejemplo, al registrar cadenas, es tentador pasar la variable de cadena como único argumento a NSLog :

NSString *aString = // get a string from somewhere; NSLog(aString);

El problema con esto es que la cadena puede contener caracteres que se interpretan como cadenas de formato. Esto puede llevar a problemas erróneos de salida, bloqueos y seguridad. En su lugar, debe sustituir la variable de cadena en una cadena de formato:

NSLog(@"%@", aString);


Ordenar las cadenas como el usuario quiera

Cuando ordena cadenas para presentar al usuario, no debe usar el método simple compare: En su lugar, siempre debe utilizar métodos de comparación localizedCompare: como localizedCompare: o localizedCaseInsensitiveCompare:

Para obtener más detalles, consulte Buscar, comparar y ordenar cadenas .


Piensa en valores nulos.

Como señala esta pregunta , los mensajes a nil son válidos en Objective-C. Si bien esto es con frecuencia una ventaja, lo que lleva a un código más limpio y más natural, la característica puede llevar ocasionalmente a errores peculiares y difíciles de rastrear si obtiene un valor nil cuando no lo esperaba.


Propiedades declaradas

Normalmente debe usar la característica de Propiedades declaradas de Objective-C 2.0 para todas sus propiedades. Si no son públicos, agréguelos en una extensión de clase. El uso de propiedades declaradas hace que la semántica de administración de memoria sea clara de inmediato, y le facilita la verificación del método dealloc. Si agrupa las declaraciones de propiedad, puede escanearlas rápidamente y compararlas con la implementación de su método dealloc.

Debe pensar mucho antes de no marcar las propiedades como ''no atómicas''. Como se señala en la Guía de lenguaje de programación de Objective C , las propiedades son atómicas por defecto e incurren en una sobrecarga considerable. Además, el simple hecho de hacer que todas sus propiedades sean atómicas no hace que su aplicación sea segura para subprocesos. También tenga en cuenta, por supuesto, que si no especifica "no atómico" e implementa sus propios métodos de acceso (en lugar de sintetizarlos), debe implementarlos de forma atómica.


Utilice el analizador estático LLVM / Clang

NOTA: Bajo Xcode 4 esto ahora está integrado en el IDE.

Usted usa el analizador estático Clang para, como era de esperar, analizar su código C y Objective-C (aún no C ++) en Mac OS X 10.5. Es trivial de instalar y usar:

  1. Descarga la última versión desde esta página .
  2. Desde la línea de comandos, cd a su directorio de proyecto.
  3. Ejecute scan-build -k -V xcodebuild .

(Existen algunas restricciones adicionales, etc., en particular, debe analizar un proyecto en su configuración de "Depuración"; consulte http://clang.llvm.org/StaticAnalysisUsage.html para obtener más información, pero eso es más o menos lo que se reduce a)

Luego, el analizador produce un conjunto de páginas web para usted que muestran la administración de memoria probable y otros problemas básicos que el compilador no puede detectar.


@kendell

En lugar de:

@interface MyClass (private) - (void) someMethod - (void) someOtherMethod @end

Utilizar:

@interface MyClass () - (void) someMethod - (void) someOtherMethod @end

Nuevo en Objective-C 2.0.

Las extensiones de clase se describen en la Referencia de Objective-C 2.0 de Apple.

"Las extensiones de clase le permiten declarar la API adicional requerida para una clase en ubicaciones que no sean dentro del bloque de interfaz principal de la clase primaria"

Así que son parte de la clase real, y NO de una categoría (privada) además de la clase. Diferencia sutil pero importante.


Algunos de estos ya se han mencionado, pero esto es lo que se me ocurre de la cabeza:

  • Siga las reglas de denominación de KVO. Incluso si no usa KVO ahora, en mi experiencia muchas veces sigue siendo beneficioso en el futuro. Y si está utilizando KVO o enlaces, necesita saber que las cosas van a funcionar de la manera en que deben hacerlo. Esto abarca no solo los métodos de acceso y las variables de instancia, sino también las relaciones a muchos, la validación, las claves dependientes de notificación automática, etc.
  • Pon los métodos privados en una categoría. No solo la interfaz, sino también la implementación. Es bueno tener una cierta distancia conceptual entre los métodos privados y no privados. Incluyo todo en mi archivo .m
  • Poner métodos de hilo de fondo en una categoría. Lo mismo que arriba. Descubrí que es bueno mantener una barrera conceptual clara cuando estás pensando qué hay en el hilo principal y qué no.
  • Utilice la #pragma mark [section] . Por lo general, agrupo por mis propios métodos, las anulaciones de cada subclase y cualquier información o protocolo formal. Esto hace que sea mucho más fácil saltar exactamente a lo que estoy buscando. En el mismo tema, agrupe los métodos similares (como los métodos de delegado de una vista de tabla), no los pegue en ningún lugar.
  • Prefijo los métodos privados y ivars con _. Me gusta su apariencia, y es menos probable que use un ivar cuando me refiero a una propiedad por accidente.
  • No utilice métodos / propiedades de mutador en init y dealloc. Nunca me ha pasado nada malo por eso, pero puedo ver la lógica si cambias el método para hacer algo que depende del estado de tu objeto.
  • Poner IBOutlets en propiedades. De hecho, acabo de leer esto aquí, pero voy a empezar a hacerlo. Independientemente de los beneficios de la memoria, parece mejor estilísticamente (al menos para mí).
  • Evite escribir código que no necesita absolutamente. Esto realmente cubre muchas cosas, como hacer ivars cuando un #define , o almacenar en caché una matriz en lugar de clasificarla cada vez que se necesiten los datos. Hay mucho que puedo decir sobre esto, pero la conclusión es que no escriba código hasta que lo necesite, o que el generador de perfiles le indique que lo haga. Hace que las cosas sean mucho más fáciles de mantener a largo plazo.
  • Termina lo que empieces. Tener un montón de código de buggy a medio terminar es la forma más rápida de matar a un proyecto. Si necesita un método de stub que esté bien, simplemente indíquelo colocando NSLog( @"stub" ) dentro, o como quiera que haga un seguimiento de las cosas.

Asegúrese de marcar la página Magia de depuración . Esta debería ser tu primera parada cuando te golpees la cabeza contra una pared mientras intentas encontrar la fuente de un error de cacao.

Por ejemplo, le dirá cómo encontrar el método donde primero asignó la memoria que más tarde está causando bloqueos (como durante la finalización de la aplicación).


Escribir pruebas unitarias. Puedes probar muchas cosas en Cocoa que podrían ser más difíciles en otros marcos. Por ejemplo, con el código UI, generalmente puede verificar que las cosas estén conectadas como deberían estar y confiar en que funcionarán cuando se utilicen. Y puede configurar los métodos de estado e invocación de delegado fácilmente para probarlos.

Tampoco tiene visibilidad de métodos públicos frente a protegidos frente a métodos privados que le impiden escribir pruebas para sus aspectos internos.


Esto es sutil pero práctico. Si se pasa a sí mismo como delegado a otro objeto, restablezca el delegado de ese objeto antes de dealloc .

- (void)dealloc { self.someObject.delegate = NULL; self.someObject = NULL; // [super dealloc]; }

Al hacer esto, se asegura de que no se enviarán más métodos de delegado. Cuando esté a punto de dealloc y desaparecer en el éter, querrá asegurarse de que nada pueda enviarle más mensajes por accidente. Recuerde que self.someObject puede ser retenido por otro objeto (podría ser un singleton o en el grupo de autorelease o lo que sea) y hasta que le diga "¡Deje de enviarme mensajes!", Cree que su objeto a punto de ser desalojado Es un juego justo.

Entrar en este hábito te salvará de muchos choques extraños que son un dolor para depurar.

El mismo principio se aplica a Key Value Observation, y NSNotifications también.

Editar:

Aún más defensivo, cambio:

self.someObject.delegate = NULL;

dentro:

if (self.someObject.delegate == self) self.someObject.delegate = NULL;


Hay algunas cosas que comencé a hacer que no creo que sean estándar:

1) Con el advenimiento de las propiedades, ya no uso "_" para prefijar variables de clase "privadas". Después de todo, si otras clases pueden acceder a una variable, ¿no debería haber una propiedad para ella? Siempre me disgustó el prefijo "_" para hacer el código más feo, y ahora puedo omitirlo.

2) Hablando de cosas privadas, prefiero ubicar las definiciones de métodos privados dentro del archivo .m en una extensión de clase como tal:

#import "MyClass.h" @interface MyClass () - (void) someMethod; - (void) someOtherMethod; @end @implementation MyClass

¿Por qué desordenar el archivo .h con cosas que los extraños no deberían preocuparse? El empty () funciona para categorías privadas en el archivo .m, y emite advertencias de compilación si no implementa los métodos declarados.

3) He comenzado a colocar dealloc en la parte superior del archivo .m, justo debajo de las directivas de @synthesize. ¿No debería estar en la parte superior de la lista de cosas que quiere pensar en una clase? Eso es especialmente cierto en un entorno como el iPhone.

3.5) En las celdas de la tabla, haga que todos los elementos (incluida la celda) sean opacos para el rendimiento. Eso significa establecer el color de fondo apropiado en todo.

3.6) Al usar un NSURLConnection, como regla, es posible que desee implementar el método delegado:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { return nil; }

Me parece que la mayoría de las llamadas web son muy singulares y es más una excepción que la regla que deseará que las respuestas se almacenen en caché, especialmente para las llamadas de servicios web. Implementar el método como se muestra deshabilita el almacenamiento en caché de respuestas.

También de interés, son algunos buenos consejos específicos para iPhone de Joseph Mattiello (recibidos en una lista de correo de iPhone). Hay más, pero pensé que estos fueron los más útiles en general (tenga en cuenta que algunos bits ahora se han editado ligeramente desde el original para incluir detalles ofrecidos en las respuestas):

4) Solo use precisión doble si tiene que hacerlo, como cuando trabaja con CoreLocation. Asegúrese de terminar sus constantes en ''f'' para hacer que gcc las almacene como flotadores.

float val = someFloat * 2.2f;

Esto es sobre todo importante cuando algo de someFloat puede ser doble, no necesitas las matemáticas de modo mixto, ya que estás perdiendo precisión en "val" en el almacenamiento. Si bien los números de punto flotante son compatibles con el hardware en los iPhones, aún puede tomar más tiempo hacer aritmética de doble precisión en lugar de precisión simple. Referencias:

En los teléfonos más antiguos, los cálculos supuestamente funcionan a la misma velocidad, pero puede tener más componentes de precisión simple en los registros que en los dobles, por lo que para muchos cálculos, la precisión única terminará siendo más rápida.

5) Establecer sus propiedades como no nonatomic . Son atomic por defecto y en síntesis, se creará un código de semáforo para evitar problemas de subprocesos múltiples. Es probable que el 99% de usted no tenga que preocuparse por esto y el código está mucho menos hinchado y es más eficiente en memoria cuando se configura en no atómico.

6) SQLite puede ser una forma muy rápida de almacenar grandes conjuntos de datos. Una aplicación de mapas, por ejemplo, puede almacenar en caché sus mosaicos en archivos SQLite. La parte más cara es la E / S del disco. Evita muchas escrituras pequeñas enviando BEGIN; y COMMIT; Entre grandes bloques. Usamos un temporizador de 2 segundos, por ejemplo, que se reinicia en cada nuevo envío. Cuando expira, enviamos COMMIT; , lo que hace que todas tus escrituras vayan en una gran parte. SQLite almacena los datos de la transacción en el disco y, al hacer esto, el ajuste Begin / End evita la creación de muchos archivos de transacción, agrupando todas las transacciones en un solo archivo.

Además, SQL bloqueará su GUI si está en su hilo principal. Si tiene una consulta muy larga, es una buena idea almacenar sus consultas como objetos estáticos y ejecutar su SQL en un hilo separado. Asegúrese de envolver todo lo que modifique la base de datos para las cadenas de consulta en los @synchronize() {} . Para consultas cortas, simplemente deje las cosas en el hilo principal para una mayor comodidad.

Más consejos de optimización de SQLite están aquí, aunque el documento parece desactualizado, muchos de los puntos probablemente todavía sean buenos;

http://web.utk.edu/~jplyon/sqlite/SQLite_optimization_FAQ.html


No escriba Objective-C como si fuera Java / C # / C ++ / etc.

Una vez vi a un equipo acostumbrado a escribir aplicaciones web Java EE intentar escribir una aplicación de escritorio Cocoa. Como si fuera una aplicación web Java EE. Había muchos AbstractFooFactory y FooFactory e IFoo y Foo volando cuando lo único que necesitaban era una clase de Foo y posiblemente un protocolo de Fooable.

Parte de asegurarse de no hacer esto es entender realmente las diferencias en el idioma. Por ejemplo, no necesita las clases abstractas de fábrica y de fábrica anteriores porque los métodos de clase de Objective-C se distribuyen de forma tan dinámica como los métodos de instancia, y se pueden anular en subclases.


Regla de oro: si alloc entonces release !

ACTUALIZACIÓN: A menos que estés usando ARC


Resista subclasificar el mundo. En Cocoa, mucho se hace a través de la delegación y el uso del tiempo de ejecución subyacente que en otros marcos se realiza a través de subclases.

Por ejemplo, en Java usa mucho las subclases de *Listener anónimas y en .NET usa mucho las subclases EventArgs . En Cocoa, tampoco lo haces, en su lugar se usa la acción de destino.


Simple pero a menudo olvidado. Según la especificación:

En general, los métodos en diferentes clases que tienen el mismo selector (el mismo nombre) también deben compartir los mismos tipos de retorno y argumento. Esta restricción es impuesta por el compilador para permitir el enlace dinámico.

en cuyo caso, se considerará que todos los mismos selectores con nombre, incluso en clases diferentes , tienen tipos de devolución / argumento idénticos. Aquí hay un ejemplo simple.

@interface FooInt:NSObject{} -(int) print; @end @implementation FooInt -(int) print{ return 5; } @end @interface FooFloat:NSObject{} -(float) print; @end @implementation FooFloat -(float) print{ return 3.3; } @end int main (int argc, const char * argv[]) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; id f1=[[FooFloat alloc]init]; //prints 0, runtime considers [f1 print] to return int, as f1''s type is "id" and FooInt precedes FooBar NSLog(@"%f",[f1 print]); FooFloat* f2=[[FooFloat alloc]init]; //prints 3.3 expectedly as the static type is FooFloat NSLog(@"%f",[f2 print]); [f1 release]; [f2 release] [pool drain]; return 0; }


Trate de evitar lo que ahora he decidido llamar Newbiecategoryaholism. Cuando los recién llegados a Objective-C descubren categorías, a menudo se vuelven locos, agregando pequeñas categorías útiles a cada clase existente ( "¿Qué? ¡Puedo agregar un método para convertir un número a números romanos a NSNumber rock on!" ).

No hagas esto

Su código será más portátil y más fácil de entender sin docenas de pequeños métodos de categorías sobre dos docenas de clases básicas.

La mayoría de las veces, cuando realmente crees que necesitas un método de categoría para ayudar a simplificar algunos códigos, verás que nunca terminarás reutilizando el método.

También hay otros peligros, a menos que esté marcando el nombre de sus métodos de categoría (¿y quién además de la drenota totalmente loca es?) Existe la posibilidad de que Apple, o un complemento, o alguna otra cosa que se ejecute en su espacio de direcciones, también definirá la misma categoría Método con el mismo nombre con un efecto secundario ligeramente diferente ....

DE ACUERDO. Ahora que ha sido advertido, ignore "no haga esta parte". Pero ejercite extrema moderación.


Use las convenciones y terminología estándar de nomenclatura y formato de Cocoa en lugar de lo que esté acostumbrado en otro entorno. Hay muchos desarrolladores de Cocoa por ahí, y cuando otro de ellos comience a trabajar con su código, será mucho más accesible si se ve y se siente similar a otro código de Cocoa.

Ejemplos de qué hacer y qué no hacer:

  • No declare id m_something; en la interfaz de un objeto y llámelo una variable o campo miembro ; use something o _something para su nombre y _something una variable de instancia .
  • No nombre un getter -getSomething ; El nombre apropiado de Cacao es solo -something .
  • No nombrar un setter -something: debe ser -setSomething:
  • El nombre del método está entremezclado con los argumentos e incluye dos puntos; es -[NSObject performSelector:withObject:] , no NSObject::performSelector .
  • Use inter-caps (CamelCase) en los nombres de métodos, parámetros, variables, nombres de clases, etc. en lugar de barras inferiores (guiones bajos).
  • Los nombres de clase comienzan con una letra mayúscula, una variable y un nombre de método en minúscula.

Hagas lo que hagas, no uses la notación húngara al estilo de Win16 / Win32. Incluso Microsoft renunció a eso con el cambio a la plataforma .NET.


Utilice NSAssert y amigos. Uso nil como objeto válido todo el tiempo ... especialmente el envío de mensajes a nil es perfectamente válido en Obj-C. Sin embargo, si realmente quiero asegurarme del estado de una variable, utilizo NSAssert y NSParameterAssert, que ayuda a localizar problemas fácilmente.


Variables y propiedades

1 / Mantener sus encabezados limpios, ocultando la implementación
No incluya variables de instancia en su encabezado. Variables privadas puestas en la continuación de la clase como propiedades. Las variables públicas se declaran como propiedades públicas en su encabezado. Si solo se debe leer, declararlo como de solo lectura y sobrescribirlo como readwrite en la continuación de la clase. Básicamente no uso variables, solo propiedades.

2 / Dé a sus propiedades un nombre de variable no predeterminado, ejemplo:

@synthesize property = property_;

Razón 1: Atrapará los errores causados ​​por olvidarse de "uno mismo". Al asignar la propiedad. Razón 2: a partir de mis experimentos, Leak Analyzer in Instruments tiene problemas para detectar la propiedad con fugas con el nombre predeterminado.

3 / Nunca use retener o liberar directamente en las propiedades (o solo en situaciones muy excepcionales). En tu dealloc solo asigna un nulo. Las propiedades de retención están destinadas a manejar la retención / liberación por sí mismas. Nunca se sabe si un colocador no está, por ejemplo, agregando o eliminando observadores. Debes usar la variable directamente solo dentro de su establecedor y captador.

Puntos de vista

1 / Ponga cada definición de vista en un xib, si puede (la excepción suele ser la configuración dinámica de contenido y capa). Ahorra tiempo (es más fácil que escribir código), es fácil de cambiar y mantiene su código limpio.

2 / No intente optimizar las vistas disminuyendo el número de vistas. No cree UIImageView en su código en lugar de xib solo porque desea agregar subvistas en él. Utilice UIImageView como fondo en su lugar. El marco de vista puede manejar cientos de vistas sin problemas.

3 / Los IBOutlets no tienen que ser siempre retenidos (o fuertes). Tenga en cuenta que la mayoría de sus IBOutlets son parte de su jerarquía de vistas y, por lo tanto, se retienen implícitamente.

4 / Suelte todos los IBOutlets en viewDidUnload

5 / Llame a viewDidUnload desde su método dealloc. No se llama implícitamente.

Memoria

1 / Autorelease objetos cuando los creas. Muchos errores son causados ​​por mover su llamada de lanzamiento a una rama if-else o después de una declaración de retorno. La liberación en lugar de la liberación automática debe usarse solo en situaciones excepcionales, por ejemplo, cuando está esperando un runloop y no quiere que su objeto se lance automáticamente antes de tiempo.

2 / Incluso si está utilizando el conteo de referencias de Authomatic, debe comprender perfectamente cómo funcionan los métodos de liberación. El uso de la retención manual no es más complicado que el ARC, en ambos casos hay que tener en cuenta las fugas y los ciclos de retención. Considere la posibilidad de utilizar la función de retener y liberar manualmente en grandes proyectos o jerarquías de objetos complicados.

Comentarios

1 / Haga su código autodocumentado. Cada nombre de variable y nombre de método debe indicar lo que está haciendo. Si el código está escrito correctamente (necesita mucha práctica en esto), no necesitará ningún comentario de código (no es lo mismo que comentarios de documentación). Los algoritmos pueden ser complicados, pero el código debe ser siempre simple.

2 / A veces, necesitarás un comentario. Por lo general, para describir un comportamiento de código no aparente o hackear. Si siente que tiene que escribir un comentario, primero intente volver a escribir el código para que sea más sencillo y sin la necesidad de comentarios.

Sangría

1 / No aumentar demasiado la sangría. La mayor parte de su código de método debe estar sangrado en el nivel de método. Los bloques anidados (si, para etc.) disminuyen la legibilidad. Si tiene tres bloques anidados, debe intentar colocar los bloques internos en un método separado. Nunca se deben usar cuatro o más bloques anidados. Si la mayoría de su código de método está dentro de un if, niegue la condición if, por ejemplo:

if (self) { //... long initialization code ... } return self;

if (!self) { return nil; } //... long initialization code ... return self;

Entender el código C, principalmente las estructuras C

Tenga en cuenta que Obj-C es solo una capa OOP ligera sobre lenguaje C Debe comprender cómo funcionan las estructuras de código básicas en C (enumeraciones, estructuras, matrices, punteros, etc.). Ejemplo:

view.frame = CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height + 20);

es lo mismo que:

CGRect frame = view.frame; frame.size.height += 20; view.frame = frame;

Y muchos más

Mantenga su propio documento de estándares de codificación y actualícelo a menudo. Trate de aprender de sus errores. Comprenda por qué se creó un error e intente evitarlo utilizando estándares de codificación.

Nuestros estándares de codificación tienen actualmente unas 20 páginas, una mezcla de estándares de codificación de Java, estándares de Google Obj-C / C ++ y nuestros propios complementos. Documente su código, use sangría estándar estándar, espacios en blanco y líneas en blanco en los lugares correctos, etc.


Active todas las advertencias de GCC, luego desactive las que son causadas regularmente por los encabezados de Apple para reducir el ruido.

También ejecute el análisis estático Clang con frecuencia; puede habilitarlo para todas las compilaciones a través de la configuración de compilación "Run Static Analyzer".

Escribe pruebas unitarias y ejecútalas con cada compilación.



Limpiar en dealloc.

Esta es una de las cosas más fáciles de olvidar - esp. cuando la codificación a 150 mph. Siempre, siempre, siempre limpie sus atributos / variables miembro en dealloc.

Me gusta usar los atributos de Objc 2, con la nueva notación de puntos, por lo que la limpieza es indolora. A menudo tan simple como:

- (void)dealloc { self.someAttribute = NULL; [super dealloc]; }

Esto se encargará del lanzamiento y establecerá el atributo en NULL (lo que considero programación defensiva, en caso de que otro método más abajo acceda de nuevo a la variable miembro, es raro pero podría ocurrir).

Con GC activado en 10.5, esto ya no es necesario, pero es posible que aún deba limpiar otros recursos que cree, puede hacerlo en el método de finalización.


No olvide que NSWindowController y NSViewController liberarán los objetos de nivel superior de los archivos NIB que rigen.

Si carga manualmente un archivo NIB, es responsable de liberar los objetos de nivel superior de ese NIB cuando haya terminado con ellos.


Sé que pasé por alto esto cuando entré por primera vez en la programación de Cocoa.

Asegúrese de que comprende las responsabilidades de gestión de memoria con respecto a los archivos NIB. Usted es responsable de liberar los objetos de nivel superior en cualquier archivo NIB que cargue. Lea la documentación de Apple sobre el tema.


Ser más funcional .

Objective-C es un lenguaje orientado a objetos, pero consciente del estilo funcional de Cocoa Framework, y en muchos casos está diseñado para ser funcional.

  1. Hay separación de mutabilidad. Usa clases inmutables como objeto primario, y objeto mutable como secundario. Por ejemplo, use NSArray principalmente, y use NSMutableArray solo cuando lo necesite.

  2. Hay funciones puras. No tantos, comprar muchas de las API de framework están diseñadas como función pura. Mira funciones como CGRectMake()o CGAffineTransformMake(). Obviamente la forma del puntero se ve más eficiente. Sin embargo, los argumentos indirectos con punteros no pueden ofrecer efectos secundarios libres. Diseñar estructuras puramente tanto como sea posible. Separar los objetos de estado par. Se usa en -copylugar de -retaincuando se pasa un valor a otro objeto. Porque el estado compartido puede influir en la mutación para valorar en otro objeto en silencio. Así que no puede ser libre de efectos secundarios. Si tiene un valor externo desde el objeto, cópielo. Así que también es importante diseñar el estado compartido lo más mínimo posible.

Sin embargo, no tengas miedo de usar funciones impuras también.

  1. Hay perezosa evaluación. Ver algo como -[UIViewController view]propiedad. La vista no se creará cuando se crea el objeto. Se creará cuando la persona que llama lea la viewpropiedad por primera vez. UIImageno se cargará hasta que esté siendo dibujado. Hay muchas implementaciones como este diseño. Este tipo de diseños son muy útiles para la administración de recursos, pero si no conoce el concepto de evaluación perezosa, no es fácil entender el comportamiento de los mismos.

  2. Hay cierre. Use bloques de C tanto como sea posible. Esto simplificará tu vida enormemente. Pero lea una vez más acerca de la administración de bloque de memoria antes de usarlo.

  3. Hay semiautomático GC. NSAutoreleasePool. Utilizar -autoreleaseprimaria. Use manual -retain/-releasesecundario cuando realmente lo necesite. (por ejemplo: optimización de memoria, eliminación explícita de recursos)


Si está utilizando Leopard (Mac OS X 10.5) o posterior, puede usar la aplicación Instruments para encontrar y rastrear pérdidas de memoria. Después de construir su programa en Xcode, seleccione Ejecutar> Iniciar con herramienta de rendimiento> Fugas.

Incluso si su aplicación no muestra ninguna fuga, es posible que mantenga los objetos por mucho tiempo. En Instrumentos, puede usar el instrumento ObjectAlloc para esto. Seleccione el instrumento ObjectAlloc en su documento de Instrumentos y muestre los detalles del instrumento (si aún no se muestra) seleccionando Ver> Detalles (debería tener una marca de verificación al lado). En "Vida útil de asignación" en el detalle de ObjectAlloc, asegúrese de elegir el botón de opción junto a "Creado y vivo".

Ahora, cuando deje de grabar su aplicación, al seleccionar la herramienta ObjectAlloc le mostrará cuántas referencias hay de cada objeto que aún vive en su aplicación en la columna "# Net". Asegúrese de no solo ver sus propias clases, sino también las clases de los objetos de nivel superior de sus archivos NIB. Por ejemplo, si no tiene ventanas en la pantalla y ve referencias a una ventana sin conexión de NS, es posible que no la haya publicado en su código.


Todos estos comentarios son excelentes, pero estoy realmente sorprendido de que nadie haya mencionado la Guía de estilo Objective-C de Google que se publicó hace un tiempo. Creo que han hecho un trabajo muy completo.


Uno bastante obvio para un principiante: utilice la función de auto-sangría de Xcode para su código. Incluso si está copiando / pegando desde otra fuente, una vez que haya pegado el código, puede seleccionar todo el bloque de código, hacer clic derecho sobre él y luego elegir la opción para volver a sangrar todo dentro de ese bloque.

Xcode realmente analizará esa sección y la sangrará basándose en corchetes, bucles, etc. Es mucho más eficiente que pulsar la barra espaciadora o la tecla de tabulación para cada una de las líneas.