Objective-C: How to check if the key and value data types are expected data types in a NSDictionary?
If your code base still uses Objective-C as of August 2019. You might want to check if your application or library crashes if you are inserting wrong data type in a NSDictionary because the Objective-C compiler does not complain if the key and value data types are not the same as the expected data type in a NSDictionary during compile time. The crash will only occur during run time. The following are the run time scenarios for the crash occurence,
- Scenario: “If you writing a unit test to check if the input parameters are expected data types.”
2. Scenario: “If you enter a different data type while running the application.”
This bug is not easy to notice until unless you do one of the above crash occurrences.
I was struggling with finding a solution to this problem and searched around the internet to find a possible solution. Only this article was close enough to my problem and it did not solve my problem but gave me a foundation to look at the NSObject method isKindOfClass.
Some background on the isKindOfClass method. This method returns a boolean when we are comparing if an object is belonging to a class or inherits from a class. For example,
if ([obj isKindOfClass:[ExampleClass class]]) {
NSLog(@"The obj belongs to this class");
} else {
NSLog(@"The obj does not belong to this class");
}
I used the method isKindOfClass to detect if the input data types are valid in a NSDictionary. I used it in two different ways. I describe them in “Solution 1” and “Solution 2”.
Solution 1:
Using keyEnumerator and objectEnumerator methods to return if the input parameters (key and value) are expected data types in a NSDictionary.
The both methods return a key and object. Using a while loop we can loop each and every key and value pairs and perform the check to see if the key and value belong or inherit from a class or not.
For example,
Here i am expecting myDictionary contains keys and values that are of type “ExampleClass”NSDictionary<ExampleClass,ExampleClass>
NSEnumerator *keyEnumerator = [myDictionary keyEnumerator];
NSEnumerator *objectEnumerator = [myDictionary objectEnumerator];id value;
id key;BOOL valid = YES;
while ((key = [keyEnumerator nextObject])) {
if (![key isKindOfClass:[ExampleClass class]]) {
NSLog(@"The key does not belong to this class");
valid = NO;
break;
}
}if (valid) {
while((value = [objectEnumerator nextObject])) {
if (![value isKindOfClass:[ExampleClass class]]) {
NSLog(@"The value does not belong to this class");
valid = NO;
break;
}
}
}
Solution 2:
Using enumerateKeysAndObjectsUsingBlock: method to return if the input parameters (key and value) are expected data types in a NSDictionary.
Using this method we can check if each and every key and value pairs belong or inherit from a class or not.
For example,
Here i am expecting myDictionary contains keys and values that are of type “ExampleClass”NSDictionary<ExampleClass,ExampleClass>
__block BOOL valid = YES;[myDictionary enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
if (![key isKindOfClass:[ExampleClass class]]) {
NSLog(@"The key does not belong to this class");
valid = NO;
*stop = YES;
}
if (![value isKindOfClass:[ExampleClass class]]) {
NSLog(@"The value does not belong to this class");
valid = NO;
*stop = YES;
}
}];
“Solution 2” is preferred over “Solution 1” as it is more readable. The “Solution 2” was possible with help from Rafael Leão.
Credits: I thank Rafael Leão for his help and reviewing this article.
If you like my articles please follow me. You can also support me by https://www.buymeacoffee.com/akarshseggemu