How to recognize if an object is a NSString in this case? - objective-c

This code
if ( [currentValue isKindOfClass:NSClassFromString(#"NSString")] ) {
CBDebug(#"this is a string");
works well when the type of currentValue is __NSCFString
but it doesn't recognize the string if the type is __NSCFConstantString
How can I fix it ?
(I'm on OSX)
thanks

Try this:
if ( [currentValue isKindOfClass:[NSString class]] ) {
CBDebug(#"this is a string");
}

Instead of checking the textstring of the class, do try the following:
[myObject isKindOfClass:[NSString class]]

Try this [obj isKindOfClass:[NSString class]];
Normally you only need NSClassFromString when testing for class names that may not be available to you.
Note: Be careful when using isKindOfClass: method on objects represented by a class cluster. Because of the nature of class clusters, the object you get back may not always be the type you expected. isKindOfClass: will return YES if the receiver somewhere inherits from the class passed as argument.

Related

Why NSDecimalNumber in a NSString?

I have an object that got parsed into an NSString and when I trace out the class name, it says NCDecimalNumber. Why? (I understand NSString is a cluster, but still don't understand why NSDecimalNumber would be a part of what's behind the cluster)
The following post asks a similar question but no one answers the why.
Converting NSDecimalNumber to NSString
This sounds like the decoder decodes the number into an NSDecimalNumber (and strings into NSStrings).
Remember, Objective-C is C, so you can effectively assign anything to a pointer, it is up to you to ensure that the types correspond. This is why you can assign an object of type NSNumber to a pointer declared to be of type NSString*. As you can see, class clusters don't have anything to do with this.
So before assigning your object to a variable, you should check the class or, alternatively, just assign the object to a pointer of type id (which can hold any object).
If you need to work on the objects based on their type, you can do something like this:
id obj = //...
if ( [obj isKindOfClass: [NSString class]] ) {
}
else if ( [obj isKindOfClass: [NSNumber class]] ) {
}
else {
}
Try to use this:
NSString *string = [[NSStrig alloc] initWithFormat:#"%#", [DecimalNumber stringValue]];
Hope that is going to help you.

How to check object is kind of block or not

How can we identify any particular object is kind of block or not?
for example,
NSSet *set =[NSSet setWithObjects:
#"name1",
#"name2",
[^{ /* ..... some code */ } copy],
nil];
How can we find out which object from set is kind of block?
There is a safer way to determine if something is a block without actually using private api or constructing a class using the private string name:
- (BOOL)isBlock:(id)item {
id block = ^{};
Class blockClass = [block class];
while ([blockClass superclass] != [NSObject class]) {
blockClass = [blockClass superclass];
}
return [item isKindOfClass:blockClass];
}
Wrap your block in a class of your own:
BlockWrapper *blockWrapper = [BlockWrapper wrapperWithBlock:^{ … }];
Check for the type and extract the actual block:
if ([obj isKindOfClass:[BlockWrapper class]]) {
codeBlock = [(BlockWrapper*)obj block];
}
There is no supported way to do this. You must keep track of what objects are blocks, and what their type signatures are.
Do you have a practical use case for a set of mixed strings and blocks?
It's possible, but I wouldn't recommend doing this, because NSBlock is not a public class and its name might change in the future:
if ([obj isKindOfClass:NSClassFromString(#"NSBlock")]) {
NSLog(#"It's a block!");
}
If you only have strings and blocks, just check ![thing isKindOfClass:[NSString class]]. i.e. invert your test.
Likewise, if you have strings, numbers and blocks, check that thing is not a string or a number, and in that case it must (by deduction) be a block. Either that, or your program is incorrect and will crash.
I suppose that ![thing isKindOfClass:[NSObject class]], while not technically correct (you don't have to subclass NSObject), will probably get you want you want.

iOS NSDictionary description with members' type

I've a NSDictionary that contain non omogeneus stuff. I need to understand what types of memebers there are into.
With the [dict description] I understand the values into, but not the type.
There is a way to do that?
Thanks
You can ask each object for it's class (type) and then check if it's the type you want, using NSObject's -isKindOfClass: method. Note that if your object is, say, an NSMutableArray this would return true for [myMutableArray isKindOfClass:[NSArray class]]
Example:
id object = [myDict objectForKey:aKey];
if ([object isKindOfClass:[NSString class]])
// It's an NSString!
Source: developer.apple.com

Best way to test if object class is nil?

In objective C, what is a better way of doing this:
if ([response class] == [nil class])
response is either a NSDictionary or NSMutableDictionary
The code is working but I'm getting a "Invalid receiver type 'void *' or "comparison of distinct Objective-C types 'Class' and 'struct NSMutableDictionary *' lacks a cast" warning messages
Thanks
If you're actually looking to test [response class], instead of the value of response itself, you'll want to use
if ([response isKindOfClass:[NSNull class])
If you're looking to check if response itself is nil, I describe a nice way of doing this in this answer to a similar question.
An object's class can't be nil unless you've botched some runtime swizzling. All valid objects must be instances of a valid class. Are you trying to do something like the following?
if (!response) {
// 'response' is nil
} else if ([response isKindOfClass:[NSMutableDictionary class]]) {
// response is an NSMutableDictionary
} else if ([response isKindOfClass:[NSDictionary class]]) {
// response is an NSDictionary
// (or an NSMutableDictionary if you remove the above 'if')
}
Since you mentioned either NSDictionary or NSMutableDictionary and appear to be testing for an instances kind...
isKindOfClass: will identify whether or not the receiver is an instance of the class specified. This includes subclasses.
Note that you cannot use this to determine if a dictionary is mutable or immutable, though, as dictionaries are instances of NSCFDictionary which is a subclass of `NSMutableDictionary.
This is very much on purpose.

How do I get class information at runtime in Objective-C?

I have NSMutableArray with different objects in it of different classes. Now I want to get the class name, related stuff and also check if the respective object is NSString or not. How should I go about it?
I was trying something like the following. It wasn't working of course.
for(NSString *string in array){
NSLog(#"Name of the class : %#", [NSString stringWithCString:class_getName(Class id)];
If you're on Mac OS X, you can use [object className], it returns an NSString
for(id obj in array) NSLog(#"Name of the class: %#", [obj className]);
To check if it's a NSString, you should use something like this:
for(id obj in array) {
if ([obj isKindofClass:[NSString class]]) {
// do something
}
}
for(id object in array){
NSLog(#"Name of the class: %#", [object className]);
NSLog(#"Object is a string: %d", [object isKindOfClass:[NSString class]]);
}
Take a look at the NSObject class and protocol for other interesting methods.
I have NSMutableArray with different objects in it of different classes. Now I want to get the class name & related stuff & also check if the respective object is NSString or not.
Hold up. Why do have an array of different typed objects in the first place? Could you redo your design to avoid getting into that situation?
As others have said, -isKindOfClass: works. One downside is it generally leads to brittle code. Here your loop needs to know about all the classes that could be in the array. Sometimes this is the best you can do though.
Designs that use -respondsToSelector: tend to be a little more robust. Here your loop would need to know about the behaviors it depends on of classes in the array.