0

I have this code for searching in the AddressBook and xcode suggests me that i have potential leaks in firstName, lastName, and another object that is unknown even to xcode. I tried to release the first 2 of them and the warning disappears but my app is crashing. Also i have a random crash on this line, i got it only once but appears in crashlytics for other people. Do you see anything wrong with my code? Thanks.

ABMultiValueRef phoneNumbers = ABRecordCopyValue((__bridge ABRecordRef)evaluatedObject, kABPersonPhoneProperty);

The code. It's purpose is to group all the contacts by the first letter of the name and to duplicate the contacts in case they have multiple numbers.

- (void)filterByKeyword:(NSString*)keyword completionBlock:(AddressBookSearchCompletionBlock)completionBlock {

dispatch_async(abQueue, ^{

    [self.filteredContacts removeAllObjects];

    // Iterate over original contacts

    for (id evaluatedObject in self.allContacts) {

        CFStringRef n = ABRecordCopyCompositeName((__bridge ABRecordRef)evaluatedObject);
        NSString *name = (__bridge_transfer NSString*)n;

        if (name == nil) {
            RCLog(@"name is nil. skip this contact");
            continue;
        }
        if (keyword == nil || [[name lowercaseString] rangeOfString:keyword].location != NSNotFound)
        {
            NSString *key = [[name substringToIndex:1] uppercaseString];
            if (key == nil || [key isEqualToString:@"_"]) {
                key = @"#";
            }
            NSMutableArray *arr = [self.filteredContacts objectForKey:key];
            if (arr == nil) {
                arr = [[NSMutableArray alloc] init];
            }

            ABMultiValueRef phoneNumbers = ABRecordCopyValue((__bridge ABRecordRef)evaluatedObject, kABPersonPhoneProperty);
            signed long num = ABMultiValueGetCount(phoneNumbers);

            if (num == 0) {
                [arr addObject:evaluatedObject];
            }
            else {
                for (CFIndex i = 0; i < num; i++) {

                    if (i > 0) {
                        // Create a separate contact with the alternative phone numbers of a contact
                        NSString* phoneNumber = (__bridge_transfer NSString*) ABMultiValueCopyValueAtIndex(phoneNumbers, i);
                        NSString* phoneNumericNumber = [phoneNumber stringByTrimmingCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
                        if (phoneNumber != nil && phoneNumber.length > 0 && phoneNumericNumber.length > 0) {

                            ABRecordRef persona = ABPersonCreate();

                            CFStringRef firstName = ABRecordCopyValue((__bridge ABRecordRef)evaluatedObject, kABPersonFirstNameProperty);
                            CFStringRef lastName = ABRecordCopyValue((__bridge ABRecordRef)evaluatedObject, kABPersonLastNameProperty);
                            ABRecordSetValue (persona, kABPersonFirstNameProperty, firstName, nil);
                            ABRecordSetValue (persona, kABPersonLastNameProperty, lastName, nil);

                            ABMutableMultiValueRef multiPhone = ABMultiValueCreateMutable(kABMultiStringPropertyType);
                            bool didAddPhone = ABMultiValueAddValueAndLabel(multiPhone, (__bridge CFTypeRef)(phoneNumber), kABPersonPhoneMobileLabel, NULL);
                            if (didAddPhone){
                                ABRecordSetValue(persona, kABPersonPhoneProperty, multiPhone, nil);
                            }

                            if (ABPersonHasImageData((__bridge ABRecordRef)evaluatedObject)) {
                                ABPersonSetImageData(persona, ABPersonCopyImageDataWithFormat((__bridge ABRecordRef)evaluatedObject, kABPersonImageFormatThumbnail), nil);
                            }

                            [arr addObject:(__bridge id)persona];

                            CFRelease(multiPhone);
                            CFRelease(persona);
                        }
                    }
                    else {
                        [arr addObject:evaluatedObject];
                    }
                }
            }

            CFRelease(phoneNumbers);

            [self.filteredContacts setObject:arr forKey:key];
            RCLog(@"%i contacts for key %@", arr.count, key);
        }
    }

    self.filteredKeys = [[self.filteredContacts allKeys] sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

    dispatch_async(dispatch_get_main_queue(), ^{
        completionBlock();
    });
});

}

Cristi Băluță
  • 1,295
  • 15
  • 27
  • try this if (firstName != NULL) { CFRelease(firstName); firstName = NULL; } and also for lastName , not sure – Shankar BS Oct 16 '13 at 13:52
  • That one worked, thanks. So maybe xcode just gets confused. I put here the analysis of the code however http://img69.imageshack.us/img69/8716/enfm.jpg – Cristi Băluță Oct 16 '13 at 14:25

0 Answers0