2013-01-02 12 views
5

stavo lavorando intorno quadro AddressBook quando ho scoperto qualche perdita di memoria di diversi tipi nella mia domanda:iOS - Perdita di memoria AddressBook

Leaked Object # Address Size Responsible Library Responsible Frame 
__NSCFArray 8 <multiple> 256 Bytes AddressBook ABCMultiValueInsertAndCreateIdentifier 
__NSCFString 7 <multiple> 224 Bytes AppSupport _sqliteStatementApplyValuesFromRecordWithNullValue 
Malloc 32 Bytes 8 <multiple> 256 Bytes AddressBook ABCMultiValueInsertAndCreateIdentifier 
__NSCFArray 8 <multiple> 256 Bytes AddressBook ABCMultiValueInsertAndCreateIdentifier 
ABCMultiValue 8 <multiple> 256 Bytes AddressBook ABCMultiValueCreate 
Malloc 32 Bytes 7 <multiple> 224 Bytes AddressBook ABCMultiValueInsertAndCreateIdentifier 
__NSCFArray 7 <multiple> 224 Bytes AddressBook ABCMultiValueInsertAndCreateIdentifier 
Malloc 32 Bytes 5 <multiple> 160 Bytes AddressBook ABCMultiValueInsertAndCreateIdentifier 

Ecco il mio codice:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { 

    SDAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate]; 

    ABMultiValueRef multiRef = ABRecordCopyValue(person, kABPersonPhoneProperty); 
    NSString *number = (__bridge NSString *) ABMultiValueCopyValueAtIndex(multiRef, 0); 
    NSString *firstname = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
    NSString *lastname = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); 

    number = (number ? number : @""); 
    firstname = (firstname ? firstname : @""); 
    lastname = (lastname ? lastname : @""); 

    NSDictionary *dic = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:number, firstname, lastname, nil] forKeys:[NSArray arrayWithObjects:kSDPhoneNumberKey, kSDFirstnameKey, kSDLastnameKey, nil]]; 

    NSMutableArray *numberArray = [NSMutableArray arrayWithArray:appDelegate.contactArray]; 
    [numberArray addObject:dic]; 

    [appDelegate setContactArray:numberArray]; 

    [self.tableView reloadData]; 

    [self dismissModalViewControllerAnimated:YES]; 

    return NO; 
} 

fare qualcuno sapere quali linee sono responsabili di queste perdite?

risposta

5

In generale, qualsiasi metodo di base Core che ha Copy o Create nel nome deve trasferire la proprietà ai propri oggetti ARC oppure è necessario chiamare da solo il numero CFRelease. Pertanto, è necessario trasferire la proprietà per i tre oggetti NSString e rilasciare manualmente multiRef.

per trasferire la proprietà ad arco si dovrebbe usare CFBridgingRelease, che secondo WWDC 2012 - Modern Objective-C (circa 37:35 nel video), è ora preferibile rispetto alla tecnica precedente, __bridging_transfer (anche se, dietro le quinte, sono lo stesso cosa).

In ogni caso, le dichiarazioni dei tre NSString oggetti dovrebbero essere:

NSString *number = CFBridgingRelease(ABMultiValueCopyValueAtIndex(multiRef, 0)); 
NSString *firstname = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty)); 
NSString *lastname = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty)); 

Ciò equivale a:

NSString *number = (__bridge_transfer NSString *) ABMultiValueCopyValueAtIndex(multiRef, 0); 
NSString *firstname = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
NSString *lastname = (__bridge_transfer NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty); 

Inoltre, non dimenticare di rilasciare multiRef anche:

CFRelease(multiRef); 

A proposito, se si esegue l'analizzatore statico, credo che li avrei indicati per te Scegliere "Analizza" dal menu "Prodotto" o premere shift + comando + B.

+0

Wow, grazie mille! Niente più perdite di memoria e lo strumento Analizza è incredibile, non sapevo che fosse lì! – Yaman