如果这是在Objective C中使用自定义字符串属性的正确方法,为什么我不能提取正确的数值?

我正在修改一个早期项目,我使用标签来识别5个中的1个,16个中的1个或10个UIButtons 1个。 我想根据我对这个答案的理解,用自定义属性替换标签。

名为myInfo的属性由一个字符串后跟一个整数组成。 这可能是另一个名称的标记,但它使消息源以一种简单整数标记不能识别的方式进行唯一标识,从我的代码中清除幻数,并希望改进文档。

该属性使用类别创建

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 

当我导入objc/runtime.h时, myInfo有效

UIView的+ CustomProperties来。

  #import  @interface UIView (MyInfo) @property ( nonatomic, strong ) id myInfo; @end 

我从UIView中的方法(下面)调用类别,在那里我创建了几组按钮。

  // 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; } 

为了识别消息源,我尝试使用此方法从myInfo去除所有非数字字符。 但是,当我尝试删除非数字字符时,我的选择器方法forButtons出现问题

 - (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); 

当我构建并运行并按下按钮1时,上面的NSLog语句会生成以下日志

  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 

请注意,原始标记的long int值是正确的,即1,而从定制属性中恢复的long int是2070247168。

Q.1首先,这种方法是否正确?

Q.2如果是这样,有人可以解释为什么我从myInfo提取一个9位数字值?

首先,一个与你的问题无关的问题:你使用"_myInfo"作为关键点有点危险。 在实践中,你将会逃脱它,但它依赖于未承诺的编译器优化。 您打算编译器(可能还有链接器)将确保相同常量字符串的所有副本都引用二进制文件中的相同内存位置。 这恰好是真的,但它不是语言的一部分。 请改用选择器。

但那不是你的问题。 你的问题是这样的:

 NSLog(@"and %li", (long int)newString); 

newString (不出所料)是一个NSString* 。 所以这指出了该字符串的地址。 如果要将其转换为数字,则需要在其上调用-intValue

也就是说,我不会将这些数据编码为字符串。 将其编码为数据对象:

 @interface ButtonInfo @property (copy) NSString *name; @property (assign) NSInteger index; @end 

(如果有固定的一组,则name可以是枚举)

如果要使其更易于阅读,请添加-description方法。 使用类型系统; 它可以帮到你。 不要尝试将复杂类型编码为字符串。

使用下面的代码行:

 NSLog(@"and %li", [newString intValue]); 

你的方法是正确的。