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