La mejor manera de evitar que otros programadores llamen-init


Al diseñar una jerarquía de clases, a veces la subclase ha agregado un nuevo método initWithSomeNewParam, y sería deseable deshabilitar las llamadas al antiguo método init heredado de la superclase.

En primer lugar, he leído la pregunta aquí, donde las alternativas propuestas son o bien override init para lanzar una excepción en tiempo de ejecución, o bien override y establecer valores predeterminados para las propiedades. En mi caso, no quiero proporcionar valores predeterminados, y quiero indicar claramente que el antiguo no se debe llamar al método, y en su lugar se debe usar el nuevo método con parámetros.

Así que la excepción en tiempo de ejecución está bien, pero a menos que el código sea depurado, no hay manera de que otros programadores en el equipo noten que el método antiguo ya no está destinado a ser utilizado.

Si estoy en lo correcto, no hay manera de marcar un método como "privado". Así que, aparte de agregar comentarios, ¿hay alguna manera de hacer esto?

Gracias de antemano.

Author: Community, 2012-03-09

5 answers

Puede marcar explícitamente su init como no disponible en su archivo de encabezado:

- (id) init __unavailable;

O:

- (id) init __attribute__((unavailable));

Con la sintaxis posterior, incluso puede dar una razón:

- (id) init __attribute__((unavailable("Must use initWithFoo: instead.")));

El compilador emite un error (no una advertencia) si alguien intenta llamarlo.

 104
Author: DarkDust,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-22 20:27:28

Para agregar a lo que @ DarkDust publicó, puede usar alternativamente UNAVAILABLE_ATTRIBUTE

- (id)init UNAVAILABLE_ATTRIBUTE;

Esto lanzará un error cuando un usuario intente llamar a init en una instancia de esta clase.

 4
Author: RileyE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-31 18:22:59

Marcar en desuso? Los desarrolladores serán desarrolladores, ¡no puedes detenernos a todos! ;-)

¿Cómo puedo marcar un método como obsoleto en Objective-C 2.0?

 1
Author: Jake,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:38

InitWith:Stuff y:OtherStuff nunca deberían ser más que constructores de conveniencia.

En que efectivamente deben llamar

self = [self init];

if(self)
{
    self.stuff = Stuff;
    self.other = OtherStuff;
}

Así que [object init] siempre devolverá un objeto en un estado predefinido, y [object initWithStuff:stuff] devolverá el objeto en el estado predefinido con stuff anulado.

Básicamente lo que estoy consiguiendo es, su mala práctica para desalentar [objeto init] especialmente cuando alguien subclases su subclase en el futuro....

 0
Author: Tony Million,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-09 12:58:15

Puedes marcar un método como "privado" definiendo una extensión privada para tu clase.

En su .h:

@interface MyClassName
- (void)initWithSomeNewParam:(id)param;

En su .m:

@interface MyClassName ()
- (void)init;
@end

También puede agregar una instrucción NSLog para que cuando alguien esté ejecutando el proyecto con una sesión XCODE adjunta, vea una salida de consola similar a "Por favor, no use init, use initWithSomeNewParam: en su lugar."Tenga en cuenta que este es el enfoque que Apple ha adoptado históricamente para las llamadas API obsoletas (así como el marcado en desuso en sus docs).

 -1
Author: darvids0n,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-09 13:00:04