Reputation: 385
I am trying to add ABRecordRef item into my NSMutableArray. Just learned that It's needed to cast the C TypeDef into Objective-C id type using (_bridge id). So, before adding new items into the array, I want to check if the object is already in the array. Therefore, i tried using [nsmutablearray containsObject] but it does not seem to be working. Duplicate items still get added into the array. Do you know what could be wrong here?
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{
if (![_buddiesList containsObject:(__bridge id)person]) {
[_buddiesList addObject:(__bridge id)person];
NSLog(@"Added");
}
return NO;
}
Upvotes: 3
Views: 629
Reputation: 8337
There is no NS-equivalent to ABRecordRef
and -containsObject:
simply calls -isEqual:
on all its objects to determine if there is a duplicate already included or not, so your approach can't work.
I suggest writing a wrapper class around ABRecordRef
and implementing your own -isEqual:
method there.
Update:
As pointed out by @omz, it does work, because CFEqual()
is called, thanks! Using a wrapper class around ABRecordRef is still a good idea, though.
Upvotes: 4
Reputation: 31782
The reason your containsObject:
call is failing to report the duplicate is that NSArray
uses the NSObject
method -isEqual:
to determine equality, and CF types such as ABRecordRef
do not have this method. We need to find a better way to determine equality.
The most efficient way to do this is to use an Objective-C wrapper around the AddressBook APIs, transforming each record into a bona fide NSObject
instead of just bridge-casting it. Jim Dovey's iPhoneContacts project is a well-written solution for this. To build an equality testing method on top of this, just add an isEqual:
method that uses the technique shown below for comparing the record IDs.
Alternatively, you can keep things as they are, but do a linear scan over the array each time you're about to add a record. Something like this:
BOOL foundMatch = NO;
for(id buddy in self.buddiesList)
{
if(ABRecordGetRecordID(buddy) == ABRecordGetRecordID(person))
{
foundMatch = YES;
break;
}
}
Upvotes: 2
Reputation: 682
You can try cheking your array objects against isKindOfClass.
For instance:
if ([[buddiesList objectAtIndex:i] isKindOfClass: (_bridge id)person]) {
Do some stuff;
}
Upvotes: -1