318 votos

Mejor manera de definir métodos privados para una clase en Objective-C

Acabo de empezar la programación Objective-C y tener experiencia en Java, se preguntan cómo las personas de la escritura de Objective-C de los programas de acuerdo con los métodos privados.

Entiendo que puede haber varias convenciones y hábitos y pensar acerca de esta cuestión como un agregador de las mejores técnicas de uso de la gente de tratar con los métodos privados en Objective-C.

Favor de incluir un argumento para su enfoque cuando se publiquen. ¿Por qué es bueno? Que inconvenientes tiene (que se sepa) y cómo tratar con ellos?


En cuanto a mis resultados hasta ahora.

Es posible utilizar categorías [p. ej. MyClass (Privado)] se define en MyClass.m archivo de grupo de métodos privados.

Este enfoque tiene 2 problemas:

  1. Xcode (y compilador?) no comprobar si usted definir todos los métodos en la categoría privada en las correspondientes @implementación de bloque
  2. Tienes que poner @interfaz de declarar su categoría privada en el comienzo de MyClass.m archivo, de lo contrario Xcode se queja con un mensaje como "el auto no puede responder a los mensajes "privateFoo".

El primer problema puede ser solucionado con categoría vacía [p. ej. MyClass ()].
El segundo me molesta mucho. Me gustaría ver privada métodos implementados (y define) cerca del final del archivo; no sé si eso es posible.

396voto

Alex Puntos 19842

No hay, como otros ya han dicho, una cosa así como un método privado en Objective-C. sin Embargo, a partir de Objective-C 2.0 (significado de Mac OS X Leopard, iPhone OS 2.0 y posteriores) puede crear una categoría con un vacío nombre (ej. @interface MyClass ()) llamado Extensión de la Clase. Lo que es único acerca de una extensión de la clase es que el método implementaciones deben ir en el mismo @implementation MyClass como los métodos públicos. Así que la estructura de mis clases como esta:

En el archivo .h:

@interface MyClass {
    // My Instance Variables
}

- (void)myPublicMethod;

@end

Y en el archivo .m:

@interface MyClass()

- (void)myPrivateMethod;

@end

@implementation MyClass

- (void)myPublicMethod {
    // Implementation goes here
}

- (void)myPrivateMethod {
    // Implementation goes here
}

@end

Creo que la mayor ventaja de este enfoque es que permite agrupar a su método de implementación de la funcionalidad, no por el (a veces arbitraria distinción público/privado.

34voto

Andy Puntos 15910

Aunque no soy un experto de Objective-C, personalmente sólo defino el método en la implementación de mi clase. Concedido, se debe definir antes (arriba) cualquier método llamando, pero definitivamente la menor cantidad de trabajo que hacer.

13voto

dreamlax Puntos 47152

Podrías intentar definir una función estática por debajo o por encima de su implementación que toma un puntero a la instancia. Será capaz de acceder a cualquiera de sus variables de instancias.

//.h file
@interface MyClass : Object
{
    int test;
}
- (void) someMethod: anArg;

@end


//.m file    
@implementation MyClass

static void somePrivateMethod (MyClass *myClass, id anArg)
{
    fprintf (stderr, "MyClass (%d) was passed %p", myClass->test, anArg);
}


- (void) someMethod: (id) anArg
{
    somePrivateMethod (self, anArg);
}

@end

13voto

justin Puntos 72871

La definición de sus métodos privados en la @implementation bloque es ideal para la mayoría de propósitos. Clang van a ver estos dentro de la @implementation, independientemente de la orden de declaración. No hay necesidad de declararlos en una clase de continuación (aka clase de extensión) o nombre de la categoría.

En algunos casos, usted tendrá que declarar el método en la clase de continuación (por ej. si utiliza el selector entre la clase de continuación y de la @implementation).

static funciones son muy buenas para las personas especialmente sensibles o de la velocidad crítica de los métodos privados.

Un convenio para la denominación de prefijos pueden ayudar a evitar que accidentalmente primordial métodos privados (puedo encontrar el nombre de la clase como un prefijo de seguro).

Categorías (por ej. @interface MONObject (PrivateStuff)) no son particularmente buena idea debido a los posibles colisiones entre nombres cuando la carga. Son realmente sólo es útil para el amigo o protegidos de los métodos (que muy rara vez son una buena opción). Para asegurarse de que se advirtió a la incompleta categoría implementaciones, en realidad se debe implementar es:

@implementation MONObject (PrivateStuff)
...HERE...
@end

Aquí un poco anotado hoja de trucos:

MONObject.h

@interface MONObject : NSObject

// public declaration required for clients' visibility/use.
@property (nonatomic, assign, readwrite) bool publicBool;

// public declaration required for clients' visibility/use.
- (void)publicMethod;

@end

MONObject.m

@interface MONObject ()
@property (nonatomic, assign, readwrite) bool privateBool;

// you can use a convention where the class name prefix is reserved
// for private methods this can reduce accidental overriding:
- (void)MONObject_privateMethod;

@end

// The potentially good thing about functions is that they are truly
// inaccessible; They may not be overridden, accidentally used,
// looked up via the objc runtime, and will often be eliminated from
// backtraces. Unlike methods, they can also be inlined. If unused
// (e.g. diagnostic omitted in release) or every use is inlined,
// they may be removed from the binary:
static void PrivateMethod(MONObject * pObject) {
    pObject.privateBool = true;
}

@implementation MONObject
{
    bool anIvar;
}

static void AnotherPrivateMethod(MONObject * pObject) {
    if (0 == pObject) {
        assert(0 && "invalid parameter");
        return;
    }

    // if declared in the @implementation scope, you *could* access the
    // private ivars directly (although you should rarely do this):
    pObject->anIvar = true;
}

- (void)publicMethod
{
    // declared below -- but clang can see its declaration in this
    // translation:
    [self privateMethod];
}

// no declaration required.
- (void)privateMethod
{
}

- (void)MONObject_privateMethod
{
}

@end

Otro enfoque que puede no ser evidente: una de tipos de C++ pueden ser muy rápido y ofrecer un grado mucho más alto de control, a la vez que se minimiza el número de exportar y cargar objc métodos.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X