ios - tutorial - Si esta es la forma correcta de utilizar una propiedad de cadena personalizada en Objective C, ¿por qué no puedo extraer el valor numérico correcto?
xcode manual pdf (2)
Estoy revisando un proyecto inicial en el que utilizo etiquetas para identificar 1 de 5, 1 de 16 o 1 de 10 UIButtons
. Quiero reemplazar las etiquetas con una propiedad personalizada en función de mi comprensión de esta respuesta .
La propiedad llamada myInfo
consiste en una cadena seguida de un entero. Esto bien puede ser una etiqueta con otro nombre, pero hace que una fuente de mensaje sea únicamente identificable de una manera que una etiqueta de entero simple no lo hace, borrando los números mágicos de mi código y, con suerte, mejorando la documentación.
La propiedad se crea usando una categoría
UIView + CustomProperties.m
#import "UIView+CustomProperties.h"
@implementation UIView (MyInfo)
-(void)setMyInfo:(id)info
{
objc_setAssociatedObject(self, "_myInfo", info, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(id)myInfo
{
return objc_getAssociatedObject(self, "_myInfo") ;
}
@end
Y myInfo
funciona cuando importo objc/runtime.h
UIView + CustomProperties.
#import <objc/runtime.h>
@interface UIView (MyInfo)
@property ( nonatomic, strong ) id myInfo;
@end
Llamo a la categoría desde el método (a continuación) en UIView, donde creo varios conjuntos de botones.
// define type and number of 5, 16 or 10 buttons
switch (buttonCount) {
case 5:
roundButton.myInfo = [NSString stringWithFormat:@"transpose index %i", i ];
break;
case 16:
roundButton.myInfo = [NSString stringWithFormat:@"player index %i", i ];
break;
case 10:
roundButton.myInfo = [NSString stringWithFormat:@"note index %i", i ];
break;
default:
roundButton.myInfo = @“orphan button“;
break;
}
Para identificar un origen de mensaje, he intentado quitar todos los caracteres no numéricos de myInfo
utilizando este método . Sin embargo, aparece un problema en mi método selector para forButtons
al intentar eliminar caracteres no numéricos
- (void)fromButtons:(UIButton*)button {
NSLog(@"Button %ld tapped", (long int)[button tag]);
NSLog(@"first, %@", button.myInfo);
NSString *newString = [[button.myInfo componentsSeparatedByCharactersInSet:
[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]
componentsJoinedByString:@""];
NSLog(@"then, %@", newString);
NSLog(@"and %li", (long int)newString);
Cuando construyo y ejecuto y NSLog
el botón 1, las declaraciones NSLog
anteriores producen el siguiente registro
2017-05-25 18:27:33.147 SatGam3[930:607301] Button 1 tapped
2017-05-25 18:27:33.147 SatGam3[930:607301] first, transpose index 1
2017-05-25 18:27:33.148 SatGam3[930:607301] then, 1
2017-05-25 18:27:33.148 SatGam3[930:607301] and 2070247168
Tenga en cuenta que el valor long int
para la etiqueta original es correcto, es decir, 1, mientras que el long int
recuperado de la propiedad personalizada es 2070247168.
P.1 En primer lugar, ¿es este enfoque correcto?
Q.2 En caso afirmativo, ¿alguien puede explicar por qué estoy extrayendo un valor numérico de 9 dígitos de myInfo
?
Primero, un problema que no tiene nada que ver con su problema: su uso de "_myInfo"
como clave aquí es ligeramente peligroso. En la práctica, se saldrá con la suya, pero depende de una optimización del compilador que no se promete. Estás apostando a que el compilador (y posiblemente el enlazador) se asegurará de que todas las copias de la misma cadena constante se refieran a la misma ubicación de memoria en el binario. Eso pasa a ser cierto, pero no es parte del lenguaje. Use un selector en su lugar.
Pero ese no es tu problema. Tu problema es este:
NSLog(@"and %li", (long int)newString);
newString
es (como era de esperar) un NSString*
. Entonces esto señala la dirección de esa cadena. Si desea convertir esto en un número, querrá llamar -intValue
en él.
Dicho esto, no codificaría estos datos como una cadena. Codifíquelo como un objeto de datos:
@interface ButtonInfo
@property (copy) NSString *name;
@property (assign) NSInteger index;
@end
(o el name
podría ser una enumeración si hay un conjunto fijo de ellos)
Si desea que esto sea más fácil de leer, agregue un método de -description
. Usa el sistema de tipo; está ahí para ayudarte. No intentes codificar un tipo complicado en una cadena.
Use la siguiente línea de código:
NSLog(@"and %li", [newString intValue]);
Tu enfoque es correcto.