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

问题描述:

我正在修改一个早期的项目,在这个项目中,我使用标签来识别五分之一,十六分之一或十分之一的UIButtons。我想根据我对this answer的理解,用自定义属性替换标签。如果这是在Objective C中使用自定义字符串属性的正确方法,为什么我无法提取正确的数字值?

称为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 

而且myInfo作品,当我导入objc/runtime.h

的UIView + CustomProperties来。

#import <objc/runtime.h> 

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

要使用this methodmyInfo识别我试图剥去所有非数字字符的消息源。但是问题出现在我的选择方法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.

问题1首先,is这种方法正确吗?

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

首先,与您的问题无关的问题:您在这里使用"_myInfo"作为钥匙有点危险。在实践中,你会摆脱它,但它依赖于不被承诺的编译器优化。你打赌编译器(也可能是连接器)将确保相同常量字符串的所有副本都指向二进制文件中的相同内存位置。这恰好是真的,但它不是语言的一部分。 Use a selector instead.

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

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

newString是(意料之中)的NSString*。所以这指出了该字符串的地址。如果你想把它转换成一个数字,你可以打电话给-intValue

这就是说,我不会将此数据编码为字符串。它编码为一个数据对象:

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

(或name可能是一个枚举,如果有固定其中一组)

如果你想使这个更容易阅读,添加-description方法。使用类型系统;它在那里帮助你。不要尝试将复杂类型编码为字符串。

+0

杆,这必须是被接受的答案。提供的每个解决方案都解决了使用'NSString'相关的问题,但这个答案也证实了我怀疑的东西。以另一种方式编码信息可能会更好。即使没有'-description',它已经更清晰了,并为'* name'和'index'分开了一个button属性。谢谢。 – Greg

使用下面的代码行:

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

你的做法是正确的。