I've got an object of type id
and would like to know if it contains a value for a given keyPath
:
[myObject valueForKeyPath:myKeyPath];
Now, I wrap it into a @try{ } @catch{}
block to avoid exceptions when the given keypath isn't found. Is there a nicer way to do this? Check if the given keypath exists without handling exceptions?
Thanks a lot,
Stefan
Objective-C is general-purpose language that is developed on top of C Programming language by adding features of Small Talk programming language making it an object-oriented language. It is primarily used in developing iOS and Mac OS X operating systems as well as its applications.
In my opinion, probably the biggest difference is the syntax. You can achieve essentially the same things in either language, but in my opinion the C++ syntax is simpler while some of Objective-C's features make certain tasks (such as GUI design) easier thanks to dynamic dispatch.
While Objective-C is still supported by Apple and will likely not be deprecated anytime soon, there will be no updates to the language.
Objective C can be called the super set of C language. It contains classes and objects in addition to C language. The pointers used in C language are vulnerable to security attacks. The language objective C uses null pointers and hence is type safe compared to C.
You could try this:
if ([myObject respondsToSelector:NSSelectorFromString(myKeyPath)])
{
}
However, that may not correspond to the getter you have, especially if it is a boolean value. If this doesn't work for you, let me know and I'll write you up something using reflection.
For NSManagedObjects
, an easy solution is to look at the object's entity description and see if there's an attribute with that key name. If there is, you can also take it to the next step and see what type of an attribute the value is.
Here's a simple method that given any NSManagedObject
and any NSString
as a key, will always return an NSString
:
- (NSString *)valueOfItem:(NSManagedObject *)item asStringForKey:(NSString *)key {
NSEntityDescription *entity = [item entity];
NSDictionary *attributesByName = [entity attributesByName];
NSAttributeDescription *attribute = attributesByName[key];
if (!attribute) {
return @"---No Such Attribute Key---";
}
else if ([attribute attributeType] == NSUndefinedAttributeType) {
return @"---Undefined Attribute Type---";
}
else if ([attribute attributeType] == NSStringAttributeType) {
// return NSStrings as they are
return [item valueForKey:key];
}
else if ([attribute attributeType] < NSDateAttributeType) {
// this will be all of the NSNumber types
// return them as strings
return [[item valueForKey:key] stringValue];
}
// add more "else if" cases as desired for other types
else {
return @"---Unacceptable Attribute Type---";
}
}
If the key is invalid or the value can't be made into a string, the method returns an NSString
error message (change those blocks to do whatever you want for those cases).
All of the NSNumber
attribute types are returned as their stringValue
representations. To handle other attribute types (e.g.: dates), simply add additional "else if" blocks. (see NSAttributeDescription
Class Reference for more information).
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