2010-11-04 2 views
1

J'ai actuellement un code qui ressemble à:SDK iPhone: Une bonne façon de retourner un UILabel w/o alloc

-(UIView)someMethod { 
    CGRectMake(0,0,100,100); 
    UILabel *label = [[UILabel alloc] initWithFrame:rect]; 
    return label; 
} 

Bien qu'il fonctionne il fuit évidemment la mémoire et doit être corrigé. Je pensais que le correctif serait:

UILabel *label = [UILabel initWithFrame:rect]; 

Mais le compilateur me dit que UILabel ne répond pas à initWithFrame. Je suppose que ma question est double:

a) Quelle est la bonne façon de le faire afin que je ne fuit pas la mémoire? Je suis confus quant à la raison pour laquelle [UILabel alloc] répondrait à initWithFrame mais pas UILabel par lui-même (je crois comprendre que UILabel est héritée de UIView qui ne répond à initWithFrame)

et

b).

Répondre

4

a) Vous ne pouvez pas éviter +alloc. Mais vous pouvez utiliser -autorelease pour abandonner la propriété.

-(UIView*)someMethod { 
    CGRect rect = CGRectMake(0,0,100,100); 
    UILabel *label = [[[UILabel alloc] initWithFrame:rect] autorelease]; 
    return label; 
} 

b)+alloc est une méthode de classe, et -initWithFrame: est une méthode d'instance. Ce dernier ne peut être appelé que (ou, dans la terminologie ObjC, envoyé à) une instance de UILabel. Cependant, le symbole "UILabel" est une classe, pas une instance, donc [UILabel initWithFrame:rect] ne fonctionnera pas. De même, une méthode de classe comme +alloc ne peut être appelée que sur une classe, donc [label alloc] ne fonctionnera pas.

+0

Vous l'avez. Merci! – John

+0

mais le type de retour est (UIView *) et la fonction renvoie (UILabel) !!! c'est possible ? – Maulik

+0

@Maulik: UILabel est une sous-classe de UIView. – kennytm

2

Peut-être plus comme:

-(UILabel)someMethod { 

    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0,0,100,100)]; 
    return [label autorelease]; 
    } 
0

Il suffit d'utiliser votre méthode originale et utiliser

return [label autorelease]; 

à la place.

1

a)

-(UIView *)someMethod { 
    return [[[UILabel alloc] initWithFrame:CGRectMake(0,0,100,100)] autorelease]; 
} 

b) vous malentendu la différence entre une méthode de classe et une méthode d'instance.

une méthode de classe est déclarée et utilisée comme ceci:

// declaration: notated with + 
+ (NSDocumentController *)sharedDocumentController; 
// usage 
NSDocumentController * thang = [NSDocumentController sharedDocumentController]; 

une méthode d'instance est déclarée et utilisée comme ceci:

// declaration: notated with - 
- (id)init; 
// usage: 
// + alloc is a class method 
//  this requests the class (NSObject) to allocate and return a newly allocated NSObject 
// - init is the instance method 
//  this sends a message to the NSObject instance (returned by [NSObject alloc]) 
NSObject * thang = [[NSObject alloc] init]; 

dans votre exemple, alloc renvoie une instance allouée, que vous On attend alors d'appeler une méthode d'instance init appropriée.

certaines classes fournissent des constructeurs de proximité, qui reviennent souvent une instance autoreleased:

+ (NSNumber *)numberWithInt:(int)anInt; 

mais il est pas très commun de dupliquer du code de cette manière, à moins que vous travaillez avec des sujets avancés tels que des clusters de classe. Bien sûr, il peut être judicieux d'ajouter ceci à l'interface si vous trouvez que vous avez régulièrement besoin d'une fonctionnalité particulière ou d'un constructeur de commodité.

Questions connexes