Je suis un peu nouveau avec l'objectif C et j'essaie de transmettre un argument par référence mais vous comporte comme une valeur. Savez-vous pourquoi cela ne fonctionne pas?
C'est la fonction:
- (void) checkRedColorText:(UILabel *)labelToChange {
NSComparisonResult startLaterThanEnd = [startDate compare:endDate];
if (startLaterThanEnd == NSOrderedDescending){
labelToChange.textColor = [UIColor redColor];
}
else{
labelToChange.textColor = [UIColor blackColor];
}
}
Et c'est l'appel:
UILabel *startHourLabel; // This is properly initialized in other part of the code
[self checkRedColorText:startHourLabel];
Merci pour ton aide
Objective-c seulement prend en charge les paramètres de passage par valeur. Le problème ici a probablement été déjà corrigé (puisque cette question est âgée de plus d'un an), mais je dois clarifier certaines choses en ce qui concerne les arguments et l'objectif-c.
Objectif-c est un superset strict de C, ce qui signifie que tout c fait, obj-c le fait aussi.
En regardant rapidement Wikipedia, vous pouvez voir que Function parameters are always passed by value
L'objectif-c n'est pas différent. Ce qui se passe ici, c'est que chaque fois que nous passons un objet à une fonction (dans ce cas, un uilabel *), nous passons la valeur contenue à l'adresse du pointeur.
Quoi que vous fassiez, ce sera toujours la valeur de ce que vous passez. Si vous souhaitez transmettre la valeur du Référence, vous devrez transmettre un objet ** (comme souvent vu lors du passage de Nserror).
C'est la même chose avec des scalaires, ils sont passés par la valeur, vous pouvez donc modifier la valeur de la variable que vous avez reçue dans votre méthode et qui ne modifiera pas la valeur de la variable d'origine que vous avez transmise à la fonction.
Voici un exemple pour faciliter la compréhension:
- (void)parentFunction {
int i = 0;
[self modifyValueOfPassedArgument:i];
//i == 0 still!
}
- (void)modifyValueOfPassedArgument:(NSInteger)j {
//j == 0! but j is a copied variable. It is _NOT_ i
j = 23;
//j now == 23, but this hasn't changed the value of i.
}
Si vous vouliez pouvoir modifier i, vous devriez adopter la valeur de la Référence en procédant comme suit:
- (void)parentFunction {
int i = 0; //Stack allocated. Kept it that way for sake of simplicity
[self modifyValueOfPassedReference:&i];
//i == 23!
}
- (void)modifyValueOfPassedReference:(NSInteger *)j {
//j == 0, and this points to i! We can modify i from here.
*j = 23;
//j now == 23, and i also == 23!
}
Objective-C, comme Java, n'a qu'une valeur de passage. Comme Java, des objets sont toujours accessibles via des pointeurs. Les "objets" ne sont jamais des valeurs directement, d'où vous n'abandonnez jamais ni n'abandonnez un objet. Vous passez un pointeur d'objet par valeur. Mais cela ne semble pas être le problème - vous essayez de modifier l'objet pointé par le pointeur, ce qui est parfaitement autorisé et n'a rien à voir avec la valeur transvenant par rapport à la référence. Je ne vois aucun problème avec votre code.
Dans l'objectif-C, il n'ya aucun moyen de transmettre des objets par valeur (sauf si vous le copiez explicitement, mais c'est une autre histoire). Poke autour de votre code - êtes-vous sûr que ChreveDColortextext: est appelé? Qu'en est-il de [StartDate Comparer: Enddate], n'est-ce pas jamais égal à NsordedDescendant? LabeltoChange Nil est-il?
Avez-vous modifié le code entre cette ligne
UILabel *startHourLabel;
et cette ligne?
[self checkRedColorText:startHourLabel];
Sinon, le problème est que vous réaffirmez votre variable startHourLabel
, vous perdez donc une sorte d'initialisation qui y était auparavant. Vous devriez recevoir une erreur de compilateur ici.
Voici les possibilités pour la raison pour laquelle cela ne fonctionne pas:
Vous prétendez que vous avez initialisé Starthourlabel ailleurs, mais s'il s'agit d'une étiquette d'un fichier NIB, vous ne devez pas l'initialiser du tout. Il devrait être déclaré comme iboutlet et connecté à l'étiquette dans la nib avec Builder d'interface.
Si ce n'est pas une étiquette dans la nib, vous le créez délibérément par programme, vous devez vérifier l'adresse de l'étiquette que vous initialisez et vérifiez l'adresse de l'étiquette transmise à CheckredColortext. Soit Nslog son adresse à l'initialisation et à ChreeDColortext ou à l'inspecter avec le débogueur.