Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

isKindOfClass doesn't work as expected

i'm working on a iOS5+ project (xcode 4.4.1 SDK 5.1)

i have this code inside a unit test:

[_appDelegate application:nil didFinishLaunchingWithOptions:nil];

UITabBarController *tabBarController = (UITabBarController*)_appDelegate.window.rootViewController;

NSArray *viewControllers = [tabBarController viewControllers];

UINavigationController *nc_1 = [viewControllers objectAtIndex:0];
UIViewController *vc_1 = nc_1.topViewController;

STAssertTrue([vc_1 isKindOfClass:[ScheduleViewController class]]==YES, @"UITabBarController first tab should be a ScheduleViewController class");

If i run the test, the test fail.

So i check with the debugger:

(lldb) po [ScheduleViewController class]
(id) $1 = 0x00142b04 ScheduleViewController
(lldb) po vc_1
(UIViewController *) $2 = 0x11a32dc0 <ScheduleViewController: 0x11a32dc0>
(lldb) print (BOOL) [vc_1 isKindOfClass:(Class)[ScheduleViewController class]]
(BOOL) $4 = YES
(lldb) po [vc_1 class]
(id) $5 = 0x00142b04 ScheduleViewController
(lldb) 

In application:didFinishLaunchingWithOptions: i create a ScheduleViewController and i use it as rootController of the navigation controller. The debugger say it's correct. I don't understand what is wrong with the assert above.

Someone have idea about this?

Update

The first implementation of thE assert was:

STAssertTrue([vc_1 isKindOfClass:[ScheduleViewController class]], @"UITabBarController first tab should be a ScheduleViewController class");

The assert failed at the same way.

Update 2

As suggested in the comment i try to add this piece of code before the assert:

BOOL vcBool = [vc_1 isKindOfClass:[ScheduleViewController class]];

With the debugger i see:

(lldb) print (BOOL) [vc_1 isKindOfClass:(Class)[ScheduleViewController class]]
(BOOL) $1 = YES
(lldb) print (BOOL) vcBool
(BOOL) $2 = NO
(lldb) 

Update 3

I added this line, as suggested in the comments, before the assert:

NSLog(@"vc_1=%@ class=%@", vc_1, NSStringFromClass([vc_1 class]));

From the debug console:

vc_1=<ScheduleViewController: 0x993bdb0> class=ScheduleViewController
like image 667
Luca Bartoletti Avatar asked Sep 12 '12 10:09

Luca Bartoletti


3 Answers

Converting a class name to string with NSStringFromClass will avoid problems with isKindOfClass... example:

if ([NSStringFromClass([AViewController class]) isEqualToString:NSStringFromClass([BViewController class])])
like image 123
omanosoft Avatar answered Sep 22 '22 19:09

omanosoft


I found the solution.

It's the inverse of the solution presented in the post linked by @vacawama in the comments. I had all *.m source of the app target in the test target too. While i was searching for a solution to the isKindOfClass problem i noticed a lot of warning on the console at the begin of the test session. The warnings was like this:

Class AClass is implemented in both /Application Support/iPhone Simulator/5.0/Applications/7FC68A9C-4F2C-4A30-85AD-87D8ABA7A275/App.app/App and /Developer/Xcode/DerivedData/App-fvbgaqbdupuoodgquxhlwbudpsin/Build/Products/Debug-iphonesimulator/App.octest/AppTests. One of the two will be used. Which one is undefined.

I removed all .m files of the application from test target.

Now isKindOfClass works as expected.

Thank to all for the support.

like image 22
Luca Bartoletti Avatar answered Oct 21 '22 08:10

Luca Bartoletti


You shouldn't directly compare BOOL values to YES. It's possible this is causing the issue with your assert. Here's a reference with background on the issue: http://mobiledevelopertips.com/objective-c/of-bool-and-yes.html

like image 3
Carl Veazey Avatar answered Oct 21 '22 09:10

Carl Veazey