Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS How do I compare if Objects are Equal? [duplicate]

I have a list of Objects that I pull from a web service. When I update my UITableView, I retrieve the objects again from the web service, and compare them to each other for equality. I then remove the ones that are not present, and insert the new objects, then update my UITableView. How can I test to see if the new object equals the old object? I've created a test for clarity..

requestA should equal requestC, but fails.

Is this possible to do without looking at each property value as the objects have many values?

I was originally comparing the ID only, but this doesn't work as sometimes other property values change and the ID stays the same.

    Request *requestA = [[Request alloc] init];
    Request *requestB = [[Request alloc] init];
    Request *requestC = [[Request alloc] init];

    requestA.requestID = @"1";
    requestA.productName = @"Clutch";
    requestB.requestID = @"2";
    requestB.productName = @"Wiper";
    requestC.requestID = @"1";
    requestC.productName = @"Clutch";

    if (requestA == requestB)
        NSLog(@"A == B");

    if (requestA == requestC)
        NSLog(@"A == C");

    if ([requestA isEqual:requestB])
        NSLog(@"A isEqual B");

    if ([requestA isEqual:requestC])
        NSLog(@"A isEqual C");

    // Look at the pointers:
    NSLog(@"%p", requestA);
    NSLog(@"%p", requestB);
    NSLog(@"%p", requestC);
like image 243
vinylDeveloper Avatar asked Mar 14 '26 02:03

vinylDeveloper


1 Answers

isEqual: is a method declared in NSObject Protocol. From official docs of isEqual:

This method defines what it means for instances to be equal. For example, a container object might define two containers as equal if their corresponding objects all respond YES to an isEqual: request. See the NSData, NSDictionary, NSArray, and NSString class specifications for examples of the use of this method.

If two objects are equal, they must have the same hash value. This last point is particularly important if you define isEqual: in a subclass and intend to put instances of that subclass into a collection. Make sure you also define hash in your subclass.

Thus, as Salavat Khanov pointed out in his answer:

You need to implement -isEqual: and -hash methods for your Request class.

You want to do something like this:

// TestRequest.h
@interface TestRequest : NSObject

@property (nonatomic) NSString *requestID;
@property (nonatomic) NSString *productName;

@end

// TestRequest.m
#import "TestRequest.h"

@implementation TestRequest
- (BOOL)isEqual:(TestRequest *)object {
    if (self == object) {
        return YES;
    }

    if (![self.requestID isEqual:object.requestID]) {
        return NO;
    }

    if (![self.productName isEqual:object.productName]) {
        return NO;
    }

    return YES;
}

- (NSUInteger)hash {
    // this is a very simple hash function
    return [self.requestID hash] ^ [self.productName hash];
}
@end

or you can use a custom method:

- (BOOL)isEqualToRequest:(TestRequest *)otherRequest {
    return [self.requestID isEqualToString:otherRequest.requestID] && 
           [self.productName isEqualToString:otherRequest.productName];
}
like image 179
wcd Avatar answered Mar 16 '26 18:03

wcd



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!