2010-01-14 4 views
5

Dans le code suivant:Est-ce que "LValue" ne signifie pas ce que je pense que cela signifie?

_imageView.hasHorizontalScroller = YES; 
_imageView.hasVerticalScroller = YES; 
_imageView.autohidesScrollers = YES; 

NSLog(@"scrollbar? H %p V %p hide %p", 
     &(_imageView.hasHorizontalScroller), 
     &(_imageView.hasVerticalScroller), 
     &(_imageView.autohidesScrollers)); 

Je reçois l'erreur:

Controller.m:143: error: lvalue required as unary '&' operand 
Controller.m:144: error: lvalue required as unary '&' operand 
Controller.m:145: error: lvalue required as unary '&' operand 

Notez que j'utilise ces variables comme lvalues ​​directement devant les & lignes ...

Comment peut-il se plaindre qu'une valeur n'est pas une lvalue juste après que je lui ai assigné sans erreur? Est-ce que cela a à voir avec les getters/setters magiques que l'objectif C crée?

Je pense que je dois expliquer un contexte d'expliquer pourquoi je suis en train d'obtenir l'adresse:

dans mon précédent post SO, j'ai montré le même code, l'impression% d et de trouver que, après les missions, les propriétés étaient toujours 0 pour une raison quelconque. Donc, j'ai pensé que j'essaierais d'obtenir les adresses des propriétés pour voir où elles sont stockées et peut-être que je peux comprendre pourquoi je ne leur ai pas assigné avec succès, et alors ceci est arrivé. Je pense que, comme les gens l'ont mentionné, oui, c'est probablement quand je fais l'assignation obj-c remplace secrètement cela par un appel au setter (et puis une autre magie parce que dans un autre post SO, quelqu'un d'autre mentionné que

BOOL b = [_imageView setHasVerticleScroller: YES] 

échoue, mais

BOOL b = _imageView.hasVerticalScroller = YES; 

fonctionne très bien.

+0

Juste curieux, mais pourquoi voulez-vous imprimer l'adresse de mémoire? – swegi

+0

J'essaie de comprendre pourquoi les valeurs sont tous 0 après les affectations, et espéré que savoir où ils étaient aiderait ... –

Répondre

2

_imageView.hasHorizontalScroller = YES; - vous accédez à cette ligne propriété imageView - donc vous n'avez pas réellement accès à la valeur, mais appelez setter méthode:

[_imageView setHasHorizontalScroller:YES]; // Equivalent of your code. 

Dans le deuxième exemple, vous accédez également à la propriété, mais cette fois la méthode getter est appelée et renvoie BOOL. Comme points mipadi, vous n'avez pas besoin d'utiliser & dans cette instruction NSLog.

Je suggère de lire des documents sur properties dans obj-c.

Edit:here vous pouvez trouver la discussion sur les raisons propriétés de travail dans plusieurs déclarations d'affectation comme vous l'avez mentionné:

BOOL b = _imageView.hasVerticalScroller = YES; 
+1

donc, fondamentalement, vous dites "Oui, c'est les getters/setters magiques" ... –

+0

fondamentalement, oui :) – Vladimir

3

Je ne suis pas sûr à 100%, mais je vais prendre un coup de couteau à la réponse.

Ces propriétés sont tous BOOL types, ce qui est (je crois) un unsigned char en Objective-C. (Peut-être un int, je ne me souviens pas, mais c'est quelque chose comme ça.) Donc, vous essayez de prendre l'adresse de (&) ces propriétés. Mais vous n'accédez pas directement aux ivars; Les propriétés passent par un appel de méthode pour obtenir leurs valeurs. Donc, vous essayez d'obtenir l'adresse de la valeur de retour BOOL d'une méthode, mais puisque vous n'attribuez pas la valeur à n'importe quoi, il n'y a pas d'adresse - vous avez juste la valeur.

Vous auriez le même problème si vous avez fait ceci:

static int returnOne(void) 
{ 
    return 1; 
} 

// Later... 

NSLog(@"returnOne is %p", &returnOne()); // Oops, the return value of returnOne has no address! 

Votre journal des appels devrait ressembler à ceci:

NSLog(@"scrollbar? H %d V %d hide %d", 
    _imageView.hasHorizontalScroller, 
    _imageView.hasVerticalScroller, 
    _imageView.autohidesScrollers); 
+0

mon appel de journal n'essaie pas réellement d'afficher les valeurs. Je veux les emplacements, comme une étape de débogage ... Je sais déjà que les valeurs sont tous 0, et j'essaie de comprendre pourquoi ... –

+1

Droit, mais le point est, les valeurs n'ont pas d'adresse - - ils n'ont pas d'emplacement - puisqu'ils viennent d'être renvoyés d'un appel de méthode et ne sont pas assignés. Les propriétés sont en fait des * appels de méthode * - vous n'accédez pas à la variable elle-même. – mipadi

+0

Eh bien, cela soulève la question de savoir pourquoi les affectations enchaînées fonctionnent ... mais cela peut être un autre cas particulier ... –