mavue.cadre.de l'origine.x = valeur; ne fonctionne pas - Mais pourquoi?
Je sais que je ne peux pas utiliser ce:
myView.frame.origin.x = 25.0;
et que je dois utiliser ceci à la place:
CGRect myFrame = myView.frame;
myFrame.origin.x = 25.0;
myView.frame = myFrame;
Et je le fais tout le temps, mais je ne sais pas pourquoi je dois le faire de cette façon. Je tiens à combler cette lacune dans ma compréhension. Quelqu'un peut m'expliquer ?
Aujourd'hui Xcode vous donne "l'Expression n'est cessible". Il y a quelques temps tu as une erreur de compilation "Lvalue requis comme opérande de gauche de mission".
- +1 - j'ai demandé à ce sujet depuis pas mal de temps maintenant..
Vous devez vous connecter pour publier un commentaire.
Il y a deux distincts dot syntaxes utilisées ici. Qu'ils se ressemblent, mais ils font des choses différentes en fonction de ce qu'ils fonctionnent et ce qui est fait avec elle:
myView.frame
est un raccourci pour[myView frame]
, un appel de méthode qui renvoie uneCGRect
struct en valeur.myFrame.origin.x
accède ordinaire les membres de la structure de la traditionnelle C la mode.myView.frame
est encore un raccourci, mais parce que l'instruction est une affectation, il se traduit par l'appel d'une méthode différente,[myView setFrame:myFrame]
.Dans votre ligne haut exemple, vous pouvez obtenir une copie de l'rect et l'ensemble de ses
x
, mais jamais la copier à la vue. Vous devez explicitement la distinction entre les appels de méthode, la syntaxe à point, le sucre ne peut pas la magie dans un seul appel.La raison pour laquelle cela ne fonctionne pas est due au mélange des deux syntaxes.
Tout d'abord vous avez le "." comme un raccourci pour appeler les fonctions d'accesseur (Objective-C).
Donc
Et puis theres le "." comme direct struct membre de l'accès (pure-C). Donc
La combinant en un ensemble de valeur de cas comme cela, n'est-ce pas le travail.
Parce que ...
Si on peut l'appeler
La "mavue.cadre de" la partie est égale à [mavue getFrame] et vous obtenez un copié CGRect cadre (une structure C)
La "mavue.cadre.origine" vous donne un CGPoint origine (également une structure (struct) de la copie d'un CGRect
La "mavue.cadre.de l'origine.x = 25.0" vous donne un CGFloat x de l'origine et maintenant vous voulez assigner quelque chose à elle et c'est là le problème...
Vous essayez de définir une variable d'une structure d'une structure, qui est ok, mais il n'y a pas de pointeur de la UIView de la structure, de sorte qu'il est copié à la place. Si vous copiez et ensuite, vous définissez et puis vous vous attendez à ce que l'ensemble de l'action est en quelque sorte transmis par le biais de la première à obtenir à la UIView, bien et cela ne fonctionne tout simplement pas.
Bien entendu, on pourrait se demander pourquoi Apple n'a pas seulement créé un raccourci, de sorte qu'à la fin de votre cadre copié est automatiquement réinjecte dans un auto annexé setFrame appel, je suppose que vous avez juste à vivre avec elle.
Donc n'oubliez pas, ce serait si vous souhaitez obtenir un pointeur vers l'image, mais vous ne le faites pas, vous obtenez un copié struct la place.
Donc, si vous attendez
myView.frame.origin.x = 25.0
de travail que vous indirectement attendre votre appel sera automatiquement traduit dans une sorte de[myView setFrame:[myView getFrame:frame].origin.x = 25.0]
.Eh bien, je suppose que vous pouvez admettre que c'est anormal.
Aussi imaginer si vous souhaitez obtenir un pointeur direct à la CGRect image et que vous souhaitez modifier quelque chose par le biais de ce pointeur, comment le UIView sais que c'est la taille a changé et qu'il a de se mettre à jour ? En revanche, si un [mavue setFrame:newFrame] l'appel est fait, alors UIView peut faire tout le nécessaire réajustement de lui-même.
Un
CGRect
est une structure, qui est quelque chose de standard C. UnCGRect
est pas un Objectif C de l'objet, de sorte que lorsque vous affectez à un de ses membres, pas de setter méthode est appelée. Sans une méthode de définition d'être appelé, UIKit ne sera pas en mesure de savoir que quelque chose a changé, et donc ne pas être en mesure de mettre à jour l'affichage de l'écran.Edit: comme cela a été souligné, la cession d'une copie de la struct.
Lorsque vous manipulez les données directement, pas d'accesseur est appelé, pour que l'INTERFACE utilisateur ne peut pas mettre à jour lui - même, ou en informer tous les autres composants qui veut connaître les changements.
Edit: Comme l'a souligné walkytalky, vous obtiendrez une copie des données, de sorte qu'un changement qu'il n'a aucun effet sur l'original de toute façon. L'exemple suivant le démontre: