如果这是在 Objective C 中使用自定义字符串属性的正确方法,为什么我不能提取正确的数值? [英] If this is the right way to use a customised string property in Objective C, why can’t I extract the correct numeric value?

查看:31
本文介绍了如果这是在 Objective C 中使用自定义字符串属性的正确方法,为什么我不能提取正确的数值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am revising an early project where I use tags to identify 1-of-5, 1-of-16 or 1-of-10 UIButtons. I want to replace the tags with a customised property based on my understanding of this answer.

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

The property called myInfo consists of a string followed by an integer. This may well be a tag by another name but it makes a message source uniquely identifiable in a way that a simple integer tag does not, clearing magic numbers from my code and, hopefully, improving the documentation.

属性是使用类别创建的

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

UIView+CustomProperties.

    #import <objc/runtime.h>

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

    @end

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

I call the category from the method (below) in the UIView where I create several sets of buttons.

    // 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 从 myInfo 中去除所有非数字字符方法.但是,当我尝试删除非数字字符

To identify a message source I have tried to strip away all non-numeric characters from myInfo using this method. However a problem appears in my selector method forButtons as I attempt to remove non-numeric characters

- (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 语句会生成以下日志

When I build and run and press button 1, the NSLog statements above produce the following log

    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.

Note that the long int value for the original tag is correct i.e. 1 whereas the long int recovered from the customised property is 2070247168.

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

Q.1 Firstly, is this approach correct ?

Q.2 如果是这样,谁能解释一下为什么我要从 myInfo 中提取一个 9 位数字值?

Q.2 If so, can someone please explain why am I extracting a 9-digit numeric value from myInfo ?

推荐答案

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

First, a problem that has nothing to do with your problem: Your use of "_myInfo" as the key here is slightly dangerous. In practice you're going to get away with it, but it relies on a compiler optimization that isn't promised. You're betting that the compiler (and possibly the linker) will ensure that all copies of the same constant string refer to the same memory location in the binary. That happens to be true, but it's not part of the language. Use a selector instead.

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

But that's not your problem. Your problem is this:

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

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

newString is (unsurprisingly) an NSString*. So this points the address of that string. If you want to convert this into a number, you'll want to call -intValue on it.

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

That said, I wouldn't encode this data as a string. Encode it as a data object:

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

(或者 name 可以是一个枚举,如果有固定的集合)

(or name could be an enum if there are fixed set of them)

如果您想让它更易于阅读,请添加一个 -description 方法.使用类型系统;它可以帮助您.不要尝试将复杂类型编码为字符串.

If you want to make this easier to read, add a -description method. Use the type system; it's there to help you. Don't try to encode a complicated type into a string.

这篇关于如果这是在 Objective C 中使用自定义字符串属性的正确方法,为什么我不能提取正确的数值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆