Objective-C get a class property from string
The Key Value Coding mechanism allows you to interact with a class's properties using string representations of the property names. So, for example, if your Record
class has a property called column1
, you can access that property as follows:
NSString* dataToGet = @"column1";
id value = [myRecord valueForKey:dataToGet];
You can adapt that principle to your specific needs.
Get property name as a string
You can try this:
unsigned int propertyCount = 0;
objc_property_t * properties = class_copyPropertyList([self class], &propertyCount);
NSMutableArray * propertyNames = [NSMutableArray array];
for (unsigned int i = 0; i < propertyCount; ++i) {
objc_property_t property = properties[i];
const char * name = property_getName(property);
[propertyNames addObject:[NSString stringWithUTF8String:name]];
}
free(properties);
NSLog(@"Names: %@", propertyNames);
detect the class of a property with name in objective-c
i have the name of this property as NSString
You can use the function class_getProperty(Class cls, const char *name)
to find the property for a given class. Then use property_getAttributes(objc_property_t property)
to get the property's attributes, including the encoded type string. Read the Declared Properties section of the Objective-C Runtime Programming Guide for more info.
List of class properties in Objective-C
So more precisely, you want dynamic, runtime observaion of the properties, if I got it correctly. Do something like this (implement this method on self, the class you want to introspect):
#import <objc/runtime.h>
- (NSArray *)allPropertyNames
{
unsigned count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
NSMutableArray *rv = [NSMutableArray array];
unsigned i;
for (i = 0; i < count; i++)
{
objc_property_t property = properties[i];
NSString *name = [NSString stringWithUTF8String:property_getName(property)];
[rv addObject:name];
}
free(properties);
return rv;
}
- (void *)pointerOfIvarForPropertyNamed:(NSString *)name
{
objc_property_t property = class_getProperty([self class], [name UTF8String]);
const char *attr = property_getAttributes(property);
const char *ivarName = strchr(attr, 'V') + 1;
Ivar ivar = object_getInstanceVariable(self, ivarName, NULL);
return (char *)self + ivar_getOffset(ivar);
}
Use it like this:
SomeType myProperty;
NSArray *properties = [self allPropertyNames];
NSString *firstPropertyName = [properties objectAtIndex:0];
void *propertyIvarAddress = [self getPointerOfIvarForPropertyNamed:firstPropertyName];
myProperty = *(SomeType *)propertyIvarAddress;
// Simpler alternative using KVC:
myProperty = [self valueForKey:firstPropertyName];
Hope this helps.
iOS get property class
You should probably store the class (as a string) for each property at the same time as you store the propertyName
. Maybe as a dictionary with property name as the key and class name as the value, or vice versa.
To get the class name, you can do something like this (put this right after you declare propertyName
):
NSString* propertyAttributes = [NSString stringWithUTF8String:property_getAttributes(property)];
NSArray* splitPropertyAttributes = [propertyAttributes componentsSeparatedByString:@"\""];
if ([splitPropertyAttributes count] >= 2)
{
NSLog(@"Class of property: %@", [splitPropertyAttributes objectAtIndex:1]);
}
The string handling code is because the attributes include a number of pieces of information - the exact details are specified here: https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html
Get an object properties list in Objective-C
I just managed to get the answer myself. By using the Obj-C Runtime Library, I had access to the properties the way I wanted:
- (void)myMethod {
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for(i = 0; i < outCount; i++) {
objc_property_t property = properties[i];
const char *propName = property_getName(property);
if(propName) {
const char *propType = getPropertyType(property);
NSString *propertyName = [NSString stringWithCString:propName
encoding:[NSString defaultCStringEncoding]];
NSString *propertyType = [NSString stringWithCString:propType
encoding:[NSString defaultCStringEncoding]];
...
}
}
free(properties);
}
This required me to make a 'getPropertyType' C function, which is mainly taken from an Apple code sample (can't remember right now the exact source):
static const char *getPropertyType(objc_property_t property) {
const char *attributes = property_getAttributes(property);
char buffer[1 + strlen(attributes)];
strcpy(buffer, attributes);
char *state = buffer, *attribute;
while ((attribute = strsep(&state, ",")) != NULL) {
if (attribute[0] == 'T') {
if (strlen(attribute) <= 4) {
break;
}
return (const char *)[[NSData dataWithBytes:(attribute + 3) length:strlen(attribute) - 4] bytes];
}
}
return "@";
}
How to setup a class property in objective C?
Since Xcode 8 you can define a class property in the header file of YourClass, using the "class" identifier like:
@interface YourClass : NSObject
@property (class, strong, nonatomic) NSTimer *timer;
@end
To use the class property in class methods in your implementation you need to asign a static instance variable to your class property. This allows you to use this instance variable in class methods (class methods start with "+").
@implementation YourClass
static NSTimer *_timer;
You have to create getter and setter methods for the class property, as these will not be synthesized automatic.
+ (void)setTimer:(NSTimer*)newTimer{
if (_timer == nil)
_timer = newTimer;
}
+ (NSTimer*)timer{
return _timer;
}
// your other code here ...
@end
Now you can access the class property from all over the app and other methods with the following syntax - here are some examples:
NSTimeInterval seconds = YourClass.timer.fireDate.timeIntervalSinceNow;
[[YourClass timer] invalidate];
You will always send messages to the same object, no problems with multiple instances!
Please find an Xcode 11 sample project here: GitHub sample code
get property from id class
there are many ways
you can cast it if you know the type at compile time
id property=((MyClass *)instance).myProperty;
((MyClass *)instance).myProperty = property;
or not using dot syntax
id property=[instance myProperty];
[instance setMyProperty:property];
or using valueForKey:
id property=[instance valueForKey:@"myProperty"];
[instance setValue:property forKey:@"myProperty"];
How do I get the value from a class property in Objective-C?
That should be valueForKey instead of objectForKey. objectForKey is an NSDictionary instance method.
Besides that there's a potentional mistake in your code. Your return type in the above method is string but you don't cast it to NSString before returning.Even if you're sure that it'll always return a string it's good practice to avoid any doubts. And when declaring an NSString property you should copy it rather than retaining it. And, what's the point in declaring a "me" variable if you can easily say:
[self valueForkey:paramName];
Related Topics
What's a Redirect URI? How Does It Apply to iOS App for Oauth2.0
Check If Uicolor Is Dark or Bright
Error When Trying to Obtain a Certificate: the Specified Item Could Not Be Found in the Keychain
Swift - Uibutton with Two Lines of Text
Changed Project Name in Xcode Causing Naming Error
Record Audio and Save Permanently in iOS
How to Go from Skscene to Uiviewcontroller by Code
Uicollectionview's Cell Registerclass in Swift
How to Get Location User with Cllocationmanager in Swift
How to Disable/Remove Firebaseanalytics
Core Data Multi Thread Application
Analysing Assets.Car File in iOS
Refresh Devices in Team Provisioning Profile Managed by Xcode 7
Making a Phone Call in an iOS Application