I have a bunch of simple NSManagedObject
s 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?
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With