Objective-C使用变量名称访问浮点型getters

non_at 发布于 2019-01-11 最后更新 2019-01-11 22:59 17 浏览

假设我有NSArray,名为myArray NSString(@"a0"@"a1"@"a2") 然后在快速枚举中循环到我的数组中,根据NSString构建属性。我有访问该属性的问题。 我正在尝试这样的事情:

@property (nonatomic) float a0propertyLow;
@property (nonatomic) float a0propertyHigh;
@property (nonatomic) float a1propertyLow;
@property (nonatomic) float a1propertyHigh;
..
.. etc.
for (NSString *aPos in myArray) {
    NSString *low = [NSString stringWithFormat:@"%@propertyLow",aPos];
    NSString *high = [NSString stringWithFormat:@"%@propertyHigh",aPos];
    SEL lowSel = NSSelectorFromString(low);
    SEL highSel = NSSelectorFromString(high);
    if ([self respondsToSelector:lowSel]&&[self respondsToSelector:highSel]) {
        id sumPartOne = [self performSelector:lowSel];
        id sumPartTwo = [self performSelector:highSel];
        float bla = (float)sumPartOne + (float)sumPartTwo;
    }
}
我知道我的代码是错误的,但我不知道如何使它工作。 我的问题是lowSel和highSel是返回float的getter,但执行选择器方法返回id,这对于对象来说可以,但对于floats不会。 那么,我怎样才能使用变量名访问我的float getters?我确信答案一定很简单,但似乎我的思想正在寻找一些复杂的东西(显然不工作),所以我寻求帮助:) 非常感谢您的帮助
已邀请:

jdolor

赞同来自:

您不能使用performSelector:来调用返回标量值的方法。 performSelector:的文档清楚地说明了您需要做的事情:

For methods that return anything other than an object, use NSInvocation.
NSInvocation设置稍微复杂一些,但在参数和返回类型方面更灵活。 在您的情况下,使用键值编码可能更容易:
[self valueForKey:low];
将返回类型考虑在内,并自动将float包装在NSNumber中。

trerum

赞同来自:

如果您确实需要使用这些getter方法,可以将属性更改为double并使用objc_msgSend_fpret():

#include <objc/runtime.h>
#include <objc/message.h>
double arg0 = objc_msgSend_fpret(self, lowSel);
如果你可以避免使用getter(我知道,这不是一个好习惯,但无论如何,它确实可以使用以下方法),并直接使用实例变量:
void *object_getIvarPtr(id obj, const char *name)
{
    if (!obj || !name)
    {
        return NULL;
    }
Ivar ivar = object_getInstanceVariable(obj, name, NULL);
if (!ivar)
    {
        return NULL;
    }
return ((char *)obj + ivar_getOffset(ivar));
}
float arg0 = *(float *)object_getIvarPtr(self, [lowSel UTF8String]);
希望这可以帮助。

hquia

赞同来自:

您可以做的一种方法是在运行时将浮动转换为对象,例如: -

NSString *str=[NSSTring stringWithFormat:@"%f",yourFloatValue];
然后你可以用它来回复它
[str floatValue];