rattletrap99
rattletrap99

Reputation: 1479

"If" statement mystery

I've got an if routine that compares a value with two other values (using the || operator) and if the statement evaluates to YES, the value firstActivity.stopTime should change from null to the current time [NSDate date].

However, it appears to evaluate to NO, resulting in no change, even though my NSLog readouts (and my own observations) appear to confirm that it would have to evaluate to YES.

Here's the code:

-(void) compareActivity
{
    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];
    TimedActivity *firstActivity = [TimedActivity MR_findFirstOrderedByAttribute:@"startTime" ascending:NO];

    NSLog(@"1 Currently timed activity is %@",firstActivity.name);
    NSLog(@"2 thisSpec.activityOfInterest is %@",self.thisSpec.activityOfInterest);
    NSLog(@"3 Currently timed activity stopTime is %@",firstActivity.stopTime);
    NSLog(@"4 thisSpec.benchmarkActivity is %@",self.thisSpec.benchmarkActivity);

    if (firstActivity.name == self.thisSpec.activityOfInterest || firstActivity.name == self.thisSpec.benchmarkActivity)
    {
        firstActivity.stopTime = [NSDate date];
        [localContext MR_saveToPersistentStoreAndWait];
        NSLog(@"5 Currently timed activity stopTime is %@",firstActivity.stopTime);
    }
    NSLog(@"6 Currently timed activity stopTime is %@",firstActivity.stopTime);
}

Here's the readout from the console:

2014-04-28 22:15:06.588 WMDGx[5683:a0b] 1 Currently timed activity is Test 1
2014-04-28 22:15:06.588 WMDGx[5683:a0b] 2 thisSpec.activityOfInterest is Test 1
2014-04-28 22:15:06.589 WMDGx[5683:a0b] 3 Currently timed activity stopTime is (null)
2014-04-28 22:15:06.589 WMDGx[5683:a0b] 4 thisSpec.benchmarkActivity is Test 2
2014-04-28 22:15:06.589 WMDGx[5683:a0b] 6 Currently timed activity stopTime is (null)

Any ideas or suggestions?

Thanks!

Update:

I updated my code thusly:

if ([firstActivity.name isEqualToString:self.thisSpec.activityOfInterest] || [firstActivity.name isEqualToString:self.thisSpec.benchmarkActivity])
{
    firstActivity.stopTime = [NSDate date];
    [localContext MR_saveToPersistentStoreAndWait];
    NSLog(@"5 Currently timed activity stopTime is %@",firstActivity.stopTime);
}

Now it works perfectly! Funny, I had run across this same issue once before some time back, and had actually tried changing the code, but this time I apparently did something wrong, leading me to think it was the wrong approach.

Many thanks!

Upvotes: 0

Views: 73

Answers (5)

Tommy
Tommy

Reputation: 100652

Everyone else has given the correct answer. Here's the explanation.

Objective-C grafts objects onto C by putting them beyond a pointer. What you're talking about with an NSString * is not formally a string, it is a pointer to a string, i.e. it is the memory address a string resides at. It describes the identity of a string, not the value.

So when you use == you are comparing by identity not by value. You're asking "do these two pointers point to the same description of a thing?".

You actually want to ask "do the two things at the end of these pointers have the same value?"

You can achieve that with isEqual: because most Foundation objects, and many others, implement that method to compare their value to the value of the parameter.

(aside: equality of identity implies equality of value but the converse isn't true; a common first test when implementing isEqual: in your own code is to check identity and possible be able to return YES without inspecting value)

Upvotes: 1

Anbu.Karthik
Anbu.Karthik

Reputation: 82776

if you are using pointer you need to convert == into [isEqual:] for validate the object

if (firstActivity.name isEqual self.thisSpec.activityOfInterest || firstActivity.name isEqual self.thisSpec.benchmarkActivity)
{
    firstActivity.stopTime = [NSDate date];
    [localContext MR_saveToPersistentStoreAndWait];
    NSLog(@"5 Currently timed activity stopTime is %@",firstActivity.stopTime);
}

if you are using the firstActivity.name and self.thisSpec.activityOfInterest are NSString then you need to validate using [isEqualToString:]

Upvotes: 1

FD_
FD_

Reputation: 12919

You have to change the == to isEqualToString:

if ([string1 isEqualToString:string2]){}

== for non-primitives such as NSString just compares the pointers (memory addresses), which is certainly not what you want.

Upvotes: 3

nicael
nicael

Reputation: 19049

Use isEqualTo: instead of ==.

Upvotes: 1

Bryan Chen
Bryan Chen

Reputation: 46638

you cannot use == to compare object pointer, you need to use isEqual: to compare object

[firstActivity.name isEqual: self.thisSpec.activityOfInterest] || [firstActivity.name isEqual: self.thisSpec.benchmarkActivity]

if they are NSString, you can use isEqualToString:

Upvotes: 3

Related Questions