iOS如何比较对象是否相等?

vin*_*per 2 objective-c uitableview ios

我有一个从Web服务中提取的对象列表.当我更新我的UITableView时,我再次从Web服务检索对象,并将它们相互比较以确保相等.然后我删除那些不存在的,并插入新对象,然后更新我的UITableView.如何测试新对象是否等于旧对象?为了清晰起见,我创建了一个测试..

requestA应该等于requestC,但是失败了.

这可能不用查看每个属性值,因为对象有很多值吗?

我最初只是在比较ID,但这不起作用,因为有时其他属性值会发生变化且ID保持不变.

    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);
Run Code Online (Sandbox Code Playgroud)

Sal*_*nov 6

检查这个答案:如何比较Objective-C中的对象?

您需要为您的类实现-isEqual:-hash方法Request.


wcd*_*wcd 6

isEqual:是一个声明的方法NSObject Protocol.来自官方文件isEqual:

此方法定义了实例相等的含义.例如,如果容器对象的相应对象都对isEqual:request响应YES,则容器对象可以将两个容器定义为相等.有关使用此方法的示例,请参阅NSData,NSDictionary,NSArray和NSString类规范.

如果两个对象相等,则它们必须具有相同的哈希值.如果在子类中定义isEqual:并打算将该子类的实例放入集合中,则最后一点尤为重要.确保您还在子类中定义哈希.

因此,正如Salavat Khanov在他的回答中指出的那样:

您需要为Request类实现-isEqual:和-hash方法.

你想做这样的事情:

// 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
Run Code Online (Sandbox Code Playgroud)

或者您可以使用自定义方法:

- (BOOL)isEqualToRequest:(TestRequest *)otherRequest {
    return [self.requestID isEqualToString:otherRequest.requestID] && 
           [self.productName isEqualToString:otherRequest.productName];
}
Run Code Online (Sandbox Code Playgroud)