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

时间:2015-01-16 14:19:58

标签: ios objective-c uitableview

我有一个从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);

4 个答案:

答案 0 :(得分:6)

检查此答案:How do I compare objects in Objective-C?

您需要为-isEqual:课程实施-hashRequest方法。

答案 1 :(得分:6)

isEqual:NSObject Protocol中声明的方法。来自isEqual的官方文档:

  

此方法定义了实例相等的含义。对于   例如,容器对象可能将两个容器定义为相等if   它们对应的对象都对isEqual:request响应YES。   请参阅NSData,NSDictionary,NSArray和NSString类   关于使用这种方法的例子的规范。

     

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

因此,正如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

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

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

答案 2 :(得分:1)

您需要覆盖Request对象的isEqual:以指定要比较的属性。 写......像这样:

- (BOOL)isEqual:(id)other {
    if (other == self) return YES;
    if (!other || ![other isKindOfClass:[self class]]) return NO;
    if (![(id)[self name] isEqual:[other name]]) return NO;
    // add other checks if needed
    return YES;
}

答案 3 :(得分:0)

首先关闭。 ==是检查"这两个对象实际上是相同的对象"。即它们只是两个指向相同但内存的指针。

您需要使用isEqual方法。但是,为了正确执行此操作,您需要覆盖类中的方法。

像...一样的东西。

- (BOOL)isEqual:(Request *)otherObject
{
    return [self.productName isEqual:otherObject.productName]
    && [self.requestID isEqual:otherObject.requestID];
}