How do I get the Objective-C class of an ivar?

对着背影说爱祢 提交于 2019-11-28 08:24:52

问题


I have a bunch of simple NSManagedObjects I create in a unit test. They just have a single name attribute of type NSString *. I always give my NSManagedObject the same entityName and Class name.

I want to avoid having to write the following code 30 times to set up a unit test:

@interface FooTest : GHTestCase {
Foo *foo;
}
@end
@implementation FooTest

- (void) setUp {
  [super setUp];

  foo = [NSEntityDescription insertNewObjectForEntityForName:@"Foo"
                                      inManagedObjectContext:managedObjectContext];
  foo.name = @"foo";
}
@end

Since foo is an ivar, I would think I should be able to write a macro to grab the type of foo (Foo), and use to create my Foo:

#define InsertManagedObjectByVariable(variable) \
do { \
variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])]; \
variable.name = (NSString *) CFSTR(#variable);
} while(0)

However, this causes the following warning in clang:

variable = [NSEntityDescription insertNewObjectForEntityName:NSStringFromClass([typeof(variable) class])];
                                                                               ^
                                                             Expected expression

I also thought I could try to determine the type using the objective-c runtime IVar from Ivar class_getInstanceVariable(Class cls, const char* name), but the only IVar type information available from the type encoding from ivar_getTypeEncoding is id, which isn't enough.

Can someone think of a way to obtain the type information of an IVar either at compile time or runtime?


回答1:


I haven't tried obtaining class information from an ivar, but I know that @property declarations do encode information about the class. For instance, this property declaration:

@property (copy) NSString *normalString;

results in this attribute string (retrieved using property_getAttributes()) at runtime:

T@"NSString",C,VnormalString

I've written some open source parsing code for this information.

Once you have the class name, you can convert it into an actual Class object using NSClassFromString(), and message the result from there.

Disclaimer: This probably shouldn't be depended upon for production applications, as it is undocumented.




回答2:


An id is an id. At runtime, all Objective-C objects have the same type (objc_object). This is tied up in the dynamic nature of ObjC. For example, an object can change classes at runtime, new classes can be created, and the class hierarchy can change. You can ask a specific instance what its type is (since this is stored in objc_object), but a pointer to an object is just a pointer to an object. Even less than that: it's really just a pointer to a C struct that happens to have extra memory allocated at the end (to hold subclass ivars).

Your macro seems interesting, but you'll probably need to pass the classname as the second parameter rather than autodetecting it.




回答3:


Maybe i misunderstand what you are trying to achieve. To get the class of an iVar, can't you use the class method of the iVar?

like:

NSString *aString = @"random string";
NSLog(@"%@",NSStringFromClass([aString class]));


来源:https://stackoverflow.com/questions/11265503/how-do-i-get-the-objective-c-class-of-an-ivar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!