从Objective-C中的对象获取Ivar值

时间:2009-12-29 03:23:29

标签: objective-c

有人可以发布一个示例,说明我如何得到一个双倍的实例变量值吗? 我尝试使用object_getIvar()函数但是效果不是很好,因为看起来这个函数只适用于返回对象而不是标量数据类型的变量。

4 个答案:

答案 0 :(得分:12)

如果您已经知道实例变量的名称,则可以使用KVC。假设具有对象x的双值的ivar称为“权重”,您执行NSNumber* x=[obj valueForKey:@"weight"];然后您可以通过[x doubleValue]获得双值。 同样,您可以设置包含[obj setValue:num forKey:@"weight"]的双精度值的NSNumber num。

object_getIvar()是较低级别的东西,对于获取类布局和/或获取只知道名称等的ivar的类型信息非常有用。如果KVC对您不够,可以吗?更准确地解释你想要达到的目标?

答案 1 :(得分:8)

/*
 set
 */
Ivar ivar = class_getInstanceVariable([self class], "_rate");
((void (*)(id, Ivar, CGFloat))object_setIvar)(self, ivar, rate);

/*
 get
 */
ptrdiff_t offset = ivar_getOffset(ivar);
unsigned char* bytes = (unsigned char *)(__bridge void*)self;
CGFloat floatValue = *((CGFloat *)(bytes+offset));

答案 2 :(得分:5)

虽然我完全赞同Yuji,而KVC对于绝大多数问题都是正确的方法,这个问题也可能与此有关,为了少数情况下您真正想要在ivars中探索,答案是使用object_getInstanceVariable()。例如:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface MyObject : NSObject {
    double _someDouble;
}
@property double someDouble;
@end
@implementation MyObject
@synthesize someDouble=_someDouble;
@end

int main (int argc, const char * argv[]) {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    MyObject *object = [[MyObject alloc] init];
    object.someDouble = 3.14;
    double doubleOut;
    object_getInstanceVariable(object, "_someDouble", (void**)&doubleOut);
    NSLog(@"%f", doubleOut);
    [object release];
    [pool drain];
    return 0;
}

请注意double*void**的奇怪演员表。这是正确的,需要避免警告,并且是返回对象指针的常见用例的副作用。

但你真的不应该只在极少数情况下在ivars中徘徊。

答案 3 :(得分:0)

我将分享我的答案(它与上一个答案非常相似,但是更简单并且支持ARC)。我需要访问NSTextStorage私有Ivar,但您可以使用其他任何类。我将其用作UIView

的类别方法
 - (NSString *_Nullable)ivarVlaue {
        NSTextStorage *_Nullable txtStrg;
        Ivar ivar = class_getInstanceVariable([self class], [@"property_name"   UTF8String]);
        if (!ivar){
           return nil;
        }
        txtStrg = object_getIvar(self, ivar);
        return txtStrg.string;}