plus cuenta con activar ios objective-c

ios - cuenta - nfc iphone 8 plus activar



Advertencia: Anulación del método para el inicializador designado (5)

Para prohibir la superclase NS_DESIGNATED_INITIALIZER

Puede describirlos como no disponibles e implementarlos con excepciones.

Para su ejemplo, en SettingsTableViewController.h :

@interface SettingsTableViewController : UITableViewController - (instancetype)initWithStyle:(UITableViewStyle)style NS_UNAVAILABLE; - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_UNAVAILABLE; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; - (instancetype)initInManagedObjectContext:(NSManagedObjectContext *)context withScoreKeeper:(ScoreKeeper *)scorer withWordList:(WordList *)wordlist NS_DESIGNATED_INITIALIZER; //...your class interface here @end

En SettingsTableViewController.m :

@interface SettingsTableViewController () - (instancetype)initWithStyle:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER; - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; @end @implementation SettingsTableViewController - (instancetype)initWithStyle:(UITableViewStyle)style { @throw nil; } - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil { @throw nil; } - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { @throw nil; } //...your class implementation here @end

También puede agregar NSAssert(NO, nil); antes @throw nil; para saber el archivo y el número de línea de la excepción en los registros.

Para permitir la superclase NS_DESIGNATED_INITIALIZER

Tienes que implementarlos explícitamente. Pero lo bueno sería eliminar la macro pública superflua NS_DESIGNATED_INITIALIZER para sus posibles subclases, y solo reintroducirla en privado.

Para su ejemplo, en SettingsTableViewController.h:

@interface SettingsTableViewController : UITableViewController - (instancetype)initWithStyle:(UITableViewStyle)style; - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder; - (instancetype)initInManagedObjectContext:(NSManagedObjectContext *)context withScoreKeeper:(ScoreKeeper *)scorer withWordList:(WordList *)wordlist NS_DESIGNATED_INITIALIZER; //...your class interface here @end

En SettingsTableViewController.m :

@interface SettingsTableViewController () - (instancetype)initWithStyle:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER; - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER; - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER; @end @implementation SettingsTableViewController - (instancetype)initWithStyle:(UITableViewStyle)style { return [super initWithStyle:style]; } - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil { return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; } - (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { return [super initWithCoder:aDecoder]; } //...your class implementation here @end

En ambos casos, (permitiendo o prohibiendo), no es necesario cambiar el resto de su implementación.

Programáticamente creo varias tablas y el código funcionó bien durante años. No generó ninguna advertencia hace dos semanas cuando la ejecuté por última vez. Desde entonces, me actualicé a iOS 8.3 y ahora recibo tres advertencias para cada UITableViewController.

Método anulado para el inicializador designado de la superclase ''-initWithStyle:'' no encontrado.

Método anulado para el inicializador designado de la superclase ''-initWithCoder:'' no encontrado.

Método reemplazado por el inicializador designado de la superclase ''-initWithNibName: bundle:'' no encontrado.

El código para inicializar la tabla es similar para todas mis tablas:

- (instancetype)initInManagedObjectContext:(NSManagedObjectContext *)context withScoreKeeper:(ScoreKeeper *)scorer withWordList:(WordList *)wordlist { self = [super initWithStyle:UITableViewStyleGrouped]; if (self) { _mObjContext = context; _scoreKeeper = scorer; _wordList = wordlist; } return self; }

y el .h se ve así:

@interface SettingsTableViewController : UITableViewController { UIPopoverController *popover; } - (instancetype)initInManagedObjectContext:(NSManagedObjectContext *)context withScoreKeeper:(ScoreKeeper *)scorer withWordList:(WordList *)wordlist NS_DESIGNATED_INITIALIZER;

Pensé que estaba anulando un inicializador designado invocando self = [super initWithStyle: UITableViewStyleGrouped] ;, pero creo que el compilador ahora tiene otras ideas.

Entonces, ¿cómo anulo el inicializador designado?


En caso de que alguien quiera saber más sobre el error, esto es lo que descubrí. No soy un programador, por lo que algunas partes podrían estar equivocadas.

Cuando abrí mi proyecto por primera vez con Xcode 5 y Xcode 6, me pidieron que "Convertir a Modern Objective-C sintaxis". (La última versión de Xcode lo coloca en Editar> Convertir> Convertir en moderno Objective-C sintaxis). Permití que Xcode convirtiera todo y entendiera la mayoría de los cambios. Entendí cómo funciona NS_DESIGNATED_INITIALIZER pero no por qué funciona. Como no tenía errores en el compilador y todo funcionaba igual que antes, me olvidé de ello. En la última versión de Xcode, parecen haber actualizado el compilador y eso es lo que activó mi mensaje de advertencia.

En las notas de Apple: Adoptando el Objetivo Moderno C

El uso de esta macro presenta algunas restricciones:

La implementación de un inicializador designado debe encadenarse a un método de inicio de superclase (con [superinicio ...]) que es un inicializador designado para la superclase.

La implementación de un inicializador de conveniencia (un inicializador no marcado como un inicializador designado dentro de una clase que tiene al menos un inicializador marcado como un inicializador designado) debe delegar en otro inicializador (con [self init ...]).

Si una clase proporciona uno o más inicializadores designados, debe implementar todos los inicializadores designados de su superclase.

Esto es lo que creo que pasó. Primero, recibí tres mensajes de advertencia porque UITableViewController tiene tres inicializadores designados.

> - (instancetype)initWithStyle:(UITableViewStyle)style NS_DESIGNATED_INITIALIZER; > - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil NS_DESIGNATED_INITIALIZER; > - (instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;

Violé la tercera restricción porque no implementé todos los inicializadores designados de la superclase.

Al eliminar la macro NS_DESIGNATED_INITIALIZER de los archivos .h, las advertencias desaparecen.

Entonces surge la pregunta: ¿me importa que estas clases no tengan inicializadores designados? Probablemente no. Primero, no hay otros inicializadores en estas clases, así que no llamaré accidentalmente al incorrecto. En segundo lugar, no soy un programador por capacitación, así que cuando comencé a escribir aplicaciones, utilicé el estilo de programación de procedimientos al que estaba acostumbrado. Hasta hace poco, nunca había subclasificado una clase. Así que no haré una subclasificación de esta y no habrá subclases de qué preocuparse. Ahora que sé un poco más sobre Objective C, resulta que cada clase que escribí era una subclase de una de las clases de iOS y eso realmente explica un poco acerca de por qué estaba recibiendo los errores.

Para abordar el punto de Rob. No me di cuenta de que podía crear el objeto de vista de tabla llamando a un método en su superclase. Por ejemplo, esta llamada funciona:

SettingsTableViewController *stvc = [[SettingsTableViewController alloc] initWithStyle: UITableViewStyleGrouped];

Funciona incluso cuando tengo establecido NS_DESIGNATED_INITIALIZER. Es de suponer que no se envían otras advertencias porque el compilador ya se queja de no llamar a un inicializador designado de súper.

Y siempre que las vistas llamadas en la vista de tabla no necesiten ninguno de los objetos que se pasaron, todo está bien. Si una vista que está vinculada a en la tabla necesita uno de los objetos, entonces obviamente la aplicación falla.

Como nunca deseo llamar nada más que el inicializador designado, siguiendo la sugerencia de Rob de usar NSAssert (), puedo asegurarme de que no llamo a los inicializadores designados de mi superclase, y hacer que todas las advertencias desaparezcan con este código:

- (instancetype)initWithStyle:(UITableViewStyle)style { NSAssert(NO, @"%@", @"Tried to implement with initWithStyle"); self = [self initInManagedObjectContext:nil withScoreKeeper:nil withWordList:nil]; return self; } - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { NSAssert(NO, @"%@", @"Tried to implement with initWithNibName"); self = [self initInManagedObjectContext:nil withScoreKeeper:nil withWordList:nil]; return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { NSAssert(NO, @"%@", @"Tried to implement with initWithCoder"); self = [self initInManagedObjectContext:nil withScoreKeeper:nil withWordList:nil]; return self; }

Aparece este error en el registro cuando trato de llamar a initWithStyle directamente.

*** Error de aserción en - [SettingsTableViewController initWithStyle:], /Users/jscarry/Words/Words/Settings/SettingsTableViewController.m:37

Enlaces útiles: Inicializadores designados iOS: utilizando NS_DESIGNATED_INITIALIZER

This artículo explica más acerca de por qué se implementa.


Has declarado initInManagedObjectContext:withScoreKeeper:withWordList: para ser el inicializador designado único para SettingsTableViewController . Eso significa que todos los demás inicializadores deben llamarlo. Pero heredó initWithStyle: etc., y aquellos que no llaman a su inicializador designado. Eso significa que si su objeto se crea llamando a initWithStyle: (o más importante, initWithCoder: , no se inicializará correctamente. Clang te está advirtiendo sobre eso.

Parece que lo resolvió eliminando NS_DESIGNATED_INITIALIZER , y eso es bastante común entre los desarrolladores de Cocoa. No he visto muchos desarrolladores que usen rutinariamente esa macro. Pero deja el error potencial. La solución más completa sería anular los inicializadores designados de la superclase e implementarlos como llamadas a [self initInManagedObjectContext:withScoreKeeper:withWordList:] , o implementarlos con NSAssert() para asegurarse de que fallan correctamente en lugar de hacer silenciosamente lo predeterminado ( que podría estar aquí, pero podría no serlo).

Tenga en cuenta que Swift hizo de esta situación un error. Simplemente está regresando a ObjC como una advertencia.


Llamar a [super initWithStyle:UITableViewStyleGrouped] no [super initWithStyle:UITableViewStyleGrouped] el método en la superclase; solo lo estás llamando.

Sospecho que iOS 8.3 ahora te muestra estas advertencias en Objective-C (hemos estado recibiendo estas advertencias por un tiempo en Swift).

Simplemente anularía esos métodos para deshacerte de las advertencias:

- (instancetype)initWithStyle:(UITableViewStyle)style { return [super initWithStyle:style]; }

No parece que deba hacer nada más en su caso.

Actualizar:

Intente cambiar su inicializador de conveniencia a esto:

- (instancetype)initInManagedObjectContext:(NSManagedObjectContext *)context withScoreKeeper:(ScoreKeeper *)scorer withWordList:(WordList *)wordlist { self = [self initWithStyle:UITableViewStyleGrouped]; // <-- self instead of super if (self) { _mObjContext = context; _scoreKeeper = scorer; _wordList = wordlist; } return self; }

Ese método es un inicializador de conveniencia y siempre debe llamar a uno de los inicializadores designados en la clase actual. Entonces, uno puede llamar al inicializador designado de la supervista.


Puede usar esta macro compartida por @steipete. Puede resolver el problema

#define PSPDF_NOT_DESIGNATED_INITIALIZER() PSPDF_NOT_DESIGNATED_INITIALIZER_CUSTOM(init) #define PSPDF_NOT_DESIGNATED_INITIALIZER_CUSTOM(initName) / _Pragma("clang diagnostic push") / _Pragma("clang diagnostic ignored /"-Wobjc-designated-initializers/"") / - (instancetype)initName / { do { / NSAssert2(NO, @"%@ is not the designated initializer for instances of %@.", NSStringFromSelector(_cmd), NSStringFromClass([self class])); / return nil; / } while (0); } / _Pragma("clang diagnostic pop")

Uso:

// IBLAirHomeActionsBarItem.h @interface IBLAirHomeActionsBarItem : IBLBaseView @property (nonatomic, copy, readonly) NSString *title; @property (nonatomic, strong, readonly) UIImage *image; - (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image NS_DESIGNATED_INITIALIZER; @end // IBLAirHomeActionsBarItem.m @implementation IBLAirHomeActionsBarItem PSPDF_NOT_DESIGNATED_INITIALIZER_CUSTOM(initWithFrame:(CGRect)frame) PSPDF_NOT_DESIGNATED_INITIALIZER_CUSTOM(initWithCoder:(NSCoder *)aDecoder) - (instancetype)initWithTitle:(NSString *)title image:(UIImage *)image { self = [super initWithFrame:CGRectZero]; if (self) { } return self; } @end

Cualquier inicializador no designado que reciba lanzará un error de aserción.