2010-03-06 6 views
4

J'ai une application conçue pour iPhone OS 2.x.iPhone - comment utiliser performSelector avec des paramètres complexes?

À un moment donné, j'ai ce code

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    //... previous stuff initializing the cell and the identifier 

    cell = [[[UITableViewCell alloc] 
    initWithFrame:CGRectZero 
    reuseIdentifier:myIdentifier] autorelease]; // A 


    // ... more stuff 
} 

Mais comme le sélecteur initWithFrame a été dépréciée dans la version 3.0, je dois transformer ce code en utilisant respondToSelector et performSelector ... comme ça ...

if ([cell respondsToSelector:@selector(initWithFrame:)]) { // iphone 2.0 
    // [cell performSelector:@selector(initWithFrame:) ... ???? what? 
} 

Mon problème est: comment puis-je interrompre l'appel sur A dans les appels preformSelector si je dois passer deux paramètres "initWithFrame: CGRectZero" et "reuseIdentifier: myIdentifier" ???

EDIT - Comme sugested par fbrereto, je l'ai fait

[cell performSelector:@selector(initWithFrame:reuseIdentifier:) 
    withObject:CGRectZero 
    withObject:myIdentifier]; 

L'erreur que j'ai est « type incompatible pour l'argument 2 de 'performSelector withObject: withObject'

myIdentifier est déclarée. comme celui-ci

static NSString *myIdentifier = @"Normal"; 

J'ai essayé de changer l'appel à

[cell performSelector:@selector(initWithFrame:reuseIdentifier:) 
    withObject:CGRectZero 
    withObject:[NSString stringWithString:myIdentifier]]; 

sans succès ...

L'autre point est CGRectZero pas être un objet ...

Répondre

11

Utilisez NSInvocation.


Vous pouvez également appeler directement objc_msgSend (sauter toutes les constructions complexes inutiles de haut niveau):

cell = objc_msgSend(cell, @selector(initWithFrame:reuseIdentifier:), 
        CGRectZero, myIdentifier); 
+0

Merci. J'ai utilisé votre code mais j'ai un EXC_BAD_ACCESS sur la première ligne de votre code. La raison, je suppose, est que lors de l'appel original, un ALLOC était en train de se faire et, pour une raison quelconque, je ne suis pas sûr que cette méthode alloue la cellule ... J'ai essayé la deuxième méthode. – SpaceDog

+0

J'ai découvert la solution. Votre code est presque parfait. La seule chose qui manque est d'allouer la cellule en premier. Merci! – SpaceDog

1

Le sélecteur vous cherchez à utiliser est en fait @selector(initWithFrame:reuseIdentifier:). Pour passer deux paramètres, utilisez performSelector:withObject:withObject:. Il faudra peut-être un peu d'essais et d'erreurs pour obtenir les paramètres justes, mais cela devrait fonctionner. Si ce n'est pas le cas, je recommanderais d'explorer la classe NSInvocation qui est destinée à gérer les messages plus complexes.

+7

Je ne suis pas sûr que vous pouvez passer par CGRects performSelector du tout: ils Aren Objets –

+0

merci pour la réponse. J'ai mis à jour la question pour montrer ce que j'ai fait et l'erreur que je ressens. Chpwn a aussi un bon point ici ... CGRect n'est pas un objet ... ça fait fondre mon cerveau ... – SpaceDog

+1

@chpwn: bon point; il semblerait que NSInvocation serait le meilleur (seulement?) choix ici, alors. – fbrereto

Questions connexes