0

我有这个用于在地址簿中搜索的代码,xcode 建议我在 firstName、lastName 和另一个甚至 xcode 都不知道的对象中存在潜在泄漏。我试图释放其中的前两个,警告消失了,但我的应用程序崩溃了。另外我在这条线上有一个随机崩溃,我只得到过一次,但出现在其他人的崩溃分析中。你看到我的代码有什么问题吗?谢谢。

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

编码。其目的是按姓名的第一个字母对所有联系人进行分组,并复制联系人以防他们有多个号码。

- (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();
    });
});

}

4

0 回答 0