2012-08-16 10 views
8

Tengo algunas UIViews creadas a medida que usan archivos .xib para el diseño y clases de respaldo para una configuración adicional. Creo estas clases usando alloc/init y llamando a loadNibNamed en mi método init personalizado pero al hacerlo estaba causando pérdida de memoria. Alguien señaló que la parte alloc realmente se crea un objeto de sí mismo que estaba goteando así que ajusté mi método init a éste:Forma correcta de iniciar una UIView con .xib y clase de respaldo

- (id)init 
{ 
    [self autorelease]; 
    self = [[[[NSBundle mainBundle] loadNibNamed:@"AssignmentView" owner:nil options:nil] lastObject] retain]; 
    [self setupBranding]; 

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)]; 
    [self addGestureRecognizer:tapRecognizer]; 
    [tapRecognizer release]; 

    return self; 
} 

Sin embargo, ahora cuando corro analizar código consigo esta advertencia "Volviendo 'auto', mientras no está configurado para el resultado de '[(super o self) init ...]' ". Entonces mi pregunta es ¿cuál es la forma correcta de hacer UIViews personalizados con una clase de respaldo?

Desde que se preguntó que había utilizado este código por encima de la siguiente manera:

AssignmentView * assignmentView = [[AssignmentView alloc] init]; 
[self.view addSubview:assignmentView]; 
+2

Generalmente, si carga una vista desde un xib, debe cargarla a través de 'loadNibNamed' en cualquier clase en la que esté creando y luego configurarlo en su método' awakeFromNib', sin siquiera tocar 'init' . Esta ha sido mi experiencia, de todos modos. ¿Podría quizás agregar algún código donde esté instanciando la vista y su método 'awakeFromNib'? –

+1

Creo que simplemente agregarías 'self = [super init]' en la parte superior de tu método. Sin embargo, Paul tiene razón, ya que normalmente no estás cargando la punta internamente. – Dustin

+0

Gracias, he estado tratando de evitar todo loadNibNamed y simplemente uso [[MyView alloc] init], pero si tengo que volver a trabajar con eso y en su lugar uso loadNibNamed entonces supongo que debo hacerlo. No tengo un método awakeFromNib pero todo en el init iría allí. –

Respuesta

17

obtener la vista de - [NSBundle loadNibNamed:owner:options:], continuación, establezca su marco para que coincida con los límites de su visión. En general, también querrás hacer que la vista en el pliego cambie de tamaño cuando se cambie el tamaño de su vista principal.

Tenemos una categoría UIView con estas adiciones:

- (UIView *)viewFromNib 
{ 
    Class class = [self class]; 
    NSString *nibName = NSStringFromClass(class); 
    NSArray *nibViews = [[NSBundle mainBundle] loadNibNamed:nibName owner:self options:nil]; 
    UIView *view = [nibViews objectAtIndex:0]; 
    return view; 
} 


- (void)addSubviewFromNib 
{ 
    UIView *view = [self viewFromNib]; 
    view.frame = self.bounds; 
    [self addSubview:view]; 
} 

Entonces nuestra -initWithFrame: método tiene el siguiente aspecto:

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     [self addSubviewFromNib]; 
    } 
    return self; 
} 

Sólo asegúrese de que la punta tiene el mismo nombre que el clase para que esto funcione

+0

Otra solución interesante. Me gusta, ya que no tengo que cambiar la forma en que ya estoy usando mis vistas –

+0

Sé que esto es antiguo, pero esta es una gran solución, y exactamente lo que esperaba hacer. – Armand

6

¿Consideraría utilizar el estilo de constructor de conveniencia?

+ (AssignmentView *)assignmentView 
{ 
    AssignmentView *result = [[[NSBundle mainBundle] loadNibNamed:@"AssignmentView" owner:nil options:nil] lastObject]; 
    [result setupBranding]; 

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDetected:)]; 
    [result addGestureRecognizer:tapRecognizer]; 
    [tapRecognizer release]; 

    return result; 
} 

Se le da la flexibilidad que parecen necesitar cuando la construcción de su punto de vista, pero no causa una pérdida de memoria o advertencias.

+0

Interesante, voy a dar una oportunidad. –

Cuestiones relacionadas