Nikkie
Nikkie

Reputation: 93

Why isMemberOfClass does not work

I am not clear how isMemberOfClass works. Check the example below. Why in the example below is lbl.textColor not a member? Please clear this up for me.

    UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 200, 100)];
    lbl.text = @"HI";
    lbl.textColor = [UIColor grayColor];
    [self.view addSubview:lbl];

    if ([lbl.textColor isMemberOfClass:[UIColor class]]) { // Why Not Memeber
        NSLog(@"Member");
    }else {
        NSLog(@"Not Member");
    }

    if ([lbl.text isMemberOfClass:[NSString class]]) {// Why Not Memeber
        NSLog(@"Member");
    }else {
        NSLog(@"Not Member");
    }
    if ([imgView.image isMemberOfClass:[UIImage class]]) {// Memeber
        NSLog(@"Member");
    }else {
        NSLog(@"Not Member");
    }

//Output

 2014-12-19 20:17:43.383 Demo[13720:70b] Not Member
 2014-12-19 20:17:45.883 Demo[13720:70b] Not Member
 2014-12-19 20:17:52.772 Demo[13720:70b] Member

Upvotes: 0

Views: 168

Answers (2)

Droppy
Droppy

Reputation: 9721

You will find it revealing to log the class of the colour after it's created:

lbl.textColor = [UIColor grayColor];
NSLog(@"lbl.textColor class=%@", NSStringFromClass([lbl.textColor class]));

and you will probably find the actual class is UIDeviceRGBColor or UICachedDeviceGrayColor or some such and this is because of class clustering.

Using isMemberOfClass only returns YES if the object is a member of the class specified and what you probably want is isKindOfClass which returns YES if the object is a member of the specified class or subclass.

EDIT Please note that it appears that UIColor doesn't use class clusters and the points made in @Popeye's answer are valid. My general advice would be to never use isMemberOfClass on a system class and then you don't ever need to worry about class clusters.

Upvotes: 5

Popeye
Popeye

Reputation: 12093

The 1st if statement will always be Not Memeber because you NSLog(@"Not Memeber"); for both out comes. The 1st one will return TRUE because lbl.textColor will return an instance of UIColor and the way isMemberOfClass: works is like "isMemberOfClass: Returns a Boolean value that indicates whether the receiver is an instance of a given class", taken from the Apple Documentation for NSObject. Also taken from the Apple Docs which also re-enforce that this line should return TRUE is "Class objects may be compiler-created objects but they still support the concept of membership. Thus, you can use this method to verify that the receiver is a specific Class object." and here you are checking that the class returned from textColor is of a specific class of UIColor

if ([lbl.textColor isMemberOfClass:[UIColor class]]) { //  Not Memeber
    NSLog(@"Not Memeber"); // This one is actually returned.
}else {
    NSLog(@"Not Memeber");
}

The 2nd one will always be Not Memember because lbl.text returns an NSString NOT a UILabel

if ([lbl.text isMemberOfClass:[UILabel class]]) {//Not Memeber
    NSLog(@"Memeber");
}else {
    NSLog(@"Not Memeber"); // Correctly being return 
}

The 3rd is correctly returning Memeber because imgView.image returns a UIImage.

if ([imgView.image isMemberOfClass:[UIImage class]]) {// Memeber
    NSLog(@"Memeber"); // Correctly being returned
}else {
    NSLog(@"Not Memeber");
}

Also it's spelt Member not Memeber.

EDIT

I have just done NSLog(@"lbl.textColor class=%@", NSStringFromClass([lbl.textColor class])); as per Droppy answer suggests to do and I get lbl.textColor class=UIColor so this again says that it should return true for that if statement

Upvotes: 2

Related Questions