简体   繁体   English

我如何获得ivar的Objective-C类?

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

I have a bunch of simple NSManagedObject s I create in a unit test. 我在单元测试中创建了一堆简单的NSManagedObject They just have a single name attribute of type NSString * . 它们只有一个NSString *类型的name属性。 I always give my NSManagedObject the same entityName and Class name. 我总是给我的NSManagedObject相同的entityNameClass名称。

I want to avoid having to write the following code 30 times to set up a unit test: 我想避免编写以下代码30次来设置单元测试:

@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 : 由于foo是一个ivar,我认为我应该能够编写一个宏来获取fooFoo )的类型,并用来创建我的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: 但是,这会在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. 我还以为我可以尝试使用来自Ivar class_getInstanceVariable(Class cls, const char* name)的objective-c运行时IVar来确定类型,但是来自ivar_getTypeEncoding的类型编码中唯一可用的IVar类型信息是id ,这不是足够。

Can someone think of a way to obtain the type information of an IVar either at compile time or runtime? 有人能想到一种在编译时或运行时获取IVar类型信息的方法吗?

I haven't tried obtaining class information from an ivar, but I know that @property declarations do encode information about the class. 我没有尝试从ivar获取类信息,但我知道@property声明会对该类的信息进行编码。 For instance, this property declaration: 例如,这个属性声明:

@property (copy) NSString *normalString;

results in this attribute string (retrieved using property_getAttributes() ) at runtime: 在运行时生成此属性字符串(使用property_getAttributes()检索):

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. 获得类名后,可以使用NSClassFromString()将其转换为实际的Class对象,并从那里发送结果。

Disclaimer: This probably shouldn't be depended upon for production applications, as it is undocumented. 免责声明:这可能不应该依赖于生产应用程序,因为它没有文档记录。

An id is an id . idid At runtime, all Objective-C objects have the same type ( objc_object ). 在运行时,所有Objective-C对象都具有相同的类型( objc_object )。 This is tied up in the dynamic nature of ObjC. 这与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. 您可以询问特定实例的类型(因为它存储在objc_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). 甚至还不到:它实际上只是一个指向C结构的指针,它恰好在末尾分配了额外的内存(用于保存子类ivars)。

Your macro seems interesting, but you'll probably need to pass the classname as the second parameter rather than autodetecting it. 您的宏似乎很有趣,但您可能需要将类名作为第二个参数传递而不是自动检测它。

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? 要获得iVar的类,你不能使用iVar的方法吗?

like: 喜欢:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM