0

Possible Duplicate:
isMemberOfClass returns no when ViewController is instantiated from UIStoryboard

I recently stumbled over a weird problem:

I was implementing simple Testcases and using the NSObject isMemberOfClass method to check for class equality.

Additionally I implemented a custom init:

-(id)initWithMessage:(NSString *)message

If I replace id with the right class name the isMemberOfClass will return 'YES'. Otherwise it will fail.

The interesting part is: The class Method will return the right Class every time.

Is this a bug? Or is it supposed to work that way?

Thanks..

EDIT:

Ok this did not solve the problem.. Here is what I do.. isMemberOfClass will always return NO

Testcase:

- (void)test010_broadcastWait
{
    ...
    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData
                                                           options:0 error:&error];
    Brick *newBrick = [self.parser loadBroadcastWaitBrick:doc.rootElement];
    if (![newBrick isMemberOfClass:[BroadcastWaitBrick class]])
        STFail(@"Wrong class-member");
    ....
}

BroadCastWait Class:

import "BroadcastWaitBrick.h"

@implementation BroadcastWaitBrick

-(id)initWithMessage:(NSString *)message
{
    self = [super init];
    if (self)
    {
        self.message = message;
    }
    return self;
}

...

loadMethod:

-(BroadcastWaitBrick*)loadBroadcastWaitBrick:(GDataXMLElement*)gDataXMLElement
{


    NSArray *messages = [gDataXMLElement elementsForName:@"broadcastMessage"];
    GDataXMLElement *message = (GDataXMLElement*)[messages objectAtIndex:0];

    BroadcastWaitBrick* brick = [[BroadcastWaitBrick alloc]initWithMessage:message.stringValue];

    return brick;
}
Community
  • 1
  • 1
dominik
  • 1,319
  • 13
  • 23
  • This is impossible to answer without more code. Please add the actual code you are using. – jrturton Oct 02 '12 at 15:10
  • 1
    Could you explain relation between Brick and BroadcastWaitBrick classes? – Tomasz Wojtkowiak Oct 02 '12 at 15:26
  • BroadCastWaitBrick is derived from Brick... `@interface BroadcastWaitBrick : Brick` – dominik Oct 02 '12 at 15:31
  • 1
    This is the same problem as [isMemberOfClass returns no when ViewController is instantiated from UIStoryboard](http://stackoverflow.com/questions/11675256/ismemberofclass-returns-no-when-viewcontroller-is-instantiated-from-uistoryboard); you have the class being loaded twice, one in your test code and one in your main code. This results in comparison of the two classes, which should be the same, failing. – jscs Oct 02 '12 at 16:42
  • Also, please don't accept answers that don't solve the problem for you. You are welcome to post your own solution. – jscs Oct 02 '12 at 16:46

1 Answers1

-3

isMemberOfClass in your test case returns NO because you declare newBrick var as a member of class Brick.

Better choice in this case is to use isKindOfClass method or declare newBrick as id.

Tomasz Wojtkowiak
  • 4,910
  • 1
  • 28
  • 35
  • The weird thing is, that this test works every time (eg. `BroadcastBrick` - (same implementation (difference is the class name)) but it does not work with `BroadCastWaitBrick`... Changing it to id does not help either.. – dominik Oct 02 '12 at 15:40
  • I think that difference is in definition of var which you test. In your code everything is ok, but when you create Brick class object as Brick *newBrick = [[BroadcastWaitBrick alloc] init] as the result you have to object of class Brick. – Tomasz Wojtkowiak Oct 02 '12 at 15:43
  • Ok I tried to define newBrick as BroadCastWaitBrick - but the interesting part is, that it does not work either :P – dominik Oct 02 '12 at 15:45
  • Found the solution. Even tough I do not understand it: I added BroadCastWaitBrick to the BuildPhases of my TestTarget.. BroadCastBrick was not added... If I remove the waitBrick from the Test Target it works.. What is the right approach?? – dominik Oct 02 '12 at 15:57
  • The variable holding an object pointer absolutely does not affect the success or failure of `isMemberOfClass:` or `isKindOfClass:`. The type information is gone at runtime, when these methods take place. The test is made dynamically, on the actual object. This is a fundamental part of ObjC. – jscs Oct 02 '12 at 16:45