1

I am checking if my one of the array consist the Nsobject which i have created custom way. i am using ContainsObject method.my problem is that contains object not working ever.even though i have same object in array its not returning the true value.

if([self.arrSelectedInterest containsObject:interest_ent])

i am also attaching the screen shot of my debug points which showing the value of the nsarray and comparing object and in that i found that interest_ent is a same object that contains in self.arrSelectedInterest and still it always return false.

enter image description here

anyone have any idea how to check if my nsarray of custom nsobject contains specific Object?

Following is my hash and isEqual Method which i have overriden and also shwoing my property types in nsobejct. @interface InterestEntity : JSONModel

@property (strong, nonatomic) NSString* InterestId;
@property (strong, nonatomic) NSString* Name;
@property (strong, nonatomic) NSString<Optional>* Code;
@property (strong, nonatomic) NSString<Optional>* Description;
@property (strong, nonatomic) NSArray<Optional>* Hashtags;


- (NSUInteger)hash {
    NSUInteger result = 1;
    NSUInteger prime = 31;

    result = prime * result + [self.InterestId hash];
    result = prime * result + [self.Name hash];
    result = prime * result + [self.Code hash];
    result = prime * result + [self.Description hash];
    result = prime * result + [self.Hashtags hash];
    return result;
}
- (BOOL)isEqual:(id)object {
    BOOL result = NO;

    if ([object isKindOfClass:[self class]]) {
        result = [[self InterestId] isEqualToString:[object InterestId]] &&
        [[self Name] isEqualToString:[object Name]] &&
        [[self Code] isEqualToString:[object Code]] &&[[self Description] isEqualToString:[object Description]] && [[self Hashtags] isEqual:[object Hashtags]];
    }

    return result;
}
BhavikKama
  • 8,566
  • 12
  • 94
  • 164
  • 1
    Did you properly implement the `isEqual:` and `hash` methods on your custom class? – rmaddy May 17 '15 at 04:15
  • nope i dont have that methods in my nsobject class – BhavikKama May 17 '15 at 04:16
  • 1
    That's your problem. `containsObject:` uses `isEqual:` on the objects. The default implementation simply looks at the object pointers. – rmaddy May 17 '15 at 04:17
  • can you please explain how to override this in my nsobject? – BhavikKama May 17 '15 at 04:18
  • See http://stackoverflow.com/questions/254281/best-practices-for-overriding-isequal-and-hash – rmaddy May 17 '15 at 04:25
  • You don't handle the `nil` values. Those are causing `isEqual:` to return `NO`. – rmaddy May 17 '15 at 04:40
  • `containsObject` compare pointer reference, and if both points to same memory address then it will return `true`. But in your case the memory pointer are different( `even both contains same data` ) and because of that it is returning `false`. – Yogesh Suthar May 17 '15 at 04:47
  • @YogeshSuthar This is not correct. `containsObject:` does not compare pointers, it calls `isEqual:` on the objects. – rmaddy May 17 '15 at 04:50
  • Alternatively you can use `NSDictionary` to store the custom class object as value and some identifier as key. And you can check that this identifier is present or not. – Yogesh Suthar May 17 '15 at 04:52
  • @rmaddy I have faced same issue previously and I have done some research on that and found that it compares memory address. If memory address is same it will return true and if memory address is different it will return false. May be I am wrong. :) – Yogesh Suthar May 17 '15 at 04:54
  • 2
    @YogeshSuthar This is because the default implementation of `isEqual:` is to compare memory. It has nothing to do with `containsObject:`. It's all about the implementation of `isEqual:`. As long as there is a proper implementation of `isEqual:` in the custom class then you get the desired behavior. – rmaddy May 17 '15 at 04:55
  • @rmaddy What do you mean by `As long as there is a proper implementation of isEqual: in the custom class then you get the desired behavior` ? If memory address changes, how OP can handle the issue? – Yogesh Suthar May 17 '15 at 04:58
  • @YogeshSuthar Look at the `isEqual:` method in question. That's one example of a (mostly) proper implementation. – rmaddy May 17 '15 at 04:59
  • To ovveride has and isEqual correctly that a look here http://nshipster.com/equality/ – Andrea May 17 '15 at 07:43

1 Answers1

7

the problem is in implementing isEqual method in handling nullable objects

i.e. if two strings is null isEqualToString: will return false

Here is a proper implementation to handle all cases

- (BOOL)isEqual:(id)object {
    if (object == self)
        return YES;
    if (!object || ![object isKindOfClass:[self class]])
        return NO;

    // not nullable fields
    if (![self.interestId isEqualToString:object.interestId])    
        return NO;   
    if (![self.name isEqualToString:object.name])    
        return NO;
    if (![self.code isEqualToString:object.code])    
        return NO;

    // nullable fields (2 if statements for more clean code)
    if (self.description != null && ![self.description isEqualToString:object.description])    
        return NO;    
    if (object.description != null && ![object.description isEqualToString:self.description])    
        return NO;

    if (self.hashtags != null && ![self.hashtags isEqualToString:object.hashtags])    
        return NO;    
    if (object.hashtags != null && ![object.hashtags isEqualToString:self.hashtags])    
        return NO;  


    return YES;
}
Roozbeh Zabihollahi
  • 7,207
  • 45
  • 39
Mahmoud Adam
  • 5,772
  • 5
  • 41
  • 62