简体   繁体   中英

Strange BOOL behavior in tableView (When is 1 not equal to 1?)

I'm trying to convert an existing app to use core data. I've set up my entities, and am using an NSFetchedResultsController to display data in a table view. For now, I'm just populating the database each time the app launches.

It appears to be working fine, aside from one strange issue. My entity has a BOOL value, "showStarCorner" that determines whether or not an image of a star should be shown in the table cell... so, I call something similar to this if statement when configuring each tableview cell:

if (myObject.showStarCorner == [NSNumber numberWithBool:YES]) {
    // show the star corner
}

But surprisingly that results in the star only being shown on the objects I created on that launch of the app. (objects added on previous launches of the app that should be showing the star are not)

I added an extra test, to help figure out what is wrong:

if (myObject.showStarCorner == [NSNumber numberWithBool:YES]) {
    NSLog(@"%@ == %@", myObject.showStarCorner, [NSNumber numberWithBool:YES]);
}
else if (myObject.showStarCorner != [NSNumber numberWithBool:YES]) {
    NSLog(@"%@ != %@", myObject.showStarCorner, [NSNumber numberWithBool:YES]);
}

... which results in the else statement getting called for the previously added objects:

1 != 1

As far as I know, 1 should always equal 1... so I'm completely baffled.

I would greatly appreciate any help. Could it have something to do with the new objects being created having the same attributes on each app launch? (I'm not assigning any unique ID or anything, just sorting the results by the date they were added)

NSNumber* variables are pointers, and == on pointers checks for pointer equality. Since your objects don't share the same memory location (as they were created by distinct calls to [NSNumber numberWithBool:] ), they are not considered pointer-equal (and therefore the comparison returns NO ).

Use the isEqual: method instead, which should check for value equality and is available on most classes, or get the boolValue out of your NSNumber objects and compare it.

if (myObject.showStarCorner.boolValue == YES) {
    // show the star corner
}

if ([myObject.showStarCorner isEqual:[NSNumber numberWithBool:YES]]) {
    // show the star corner
}

Objects, just because they point to the same data, are not guaranteed to be equal. You need to use the -isEqual: method to test for equality, not ==:

if ([myObject.showStarCorner isEqual: [NSNumber numberWithBool: YES]) {
    //show the star corner
}

Compare the BOOL primitives:

if ([myObject.showStarCorner boolValue] == YES) {

// Alternatively,
if ([myObject.showStarCorner boolValue]) {

Otherwise you're trying to compare memory addresses of distinct NSNumber objects, which doesn't work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM