问题描述
我正在修改一个早期项目,我使用标签来识别 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 中使用自定义字符串属性的正确方法,为什么我不能提取正确的数值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!