2010-04-10 6 views
5

Ich bin ratlos.Das Lesen der E-Mail-Adresse von Kontakten schlägt mit seltsamer Speicherproblem

Ich versuche eine Liste aller E-Mail-Adressen zu erhalten, die eine Person hat. Ich benutze die ABPeoplePickerNavigationController, um die Person auszuwählen, die alles in Ordnung scheint. Ich gründe meine

ABRecordRef personDealingWith; 

vom person Argument

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier { 

und alles scheint bis zu diesem Punkt fein auf. Wenn der folgende Code zum ersten Mal ausgeführt wird, ist alles in Ordnung. Wenn später ausgeführt, kann ich Probleme bekommen. Erstens, der Code:

Wenn kompiliert wie geschrieben, sind keine Fehler oder statische Analyse Probleme. Dieser stürzt mit einem

*** -[Not A Type retain]: message sent to deallocated instance 0x4e9dc60

Fehler.

Aber warten Sie, es gibt mehr! Ich kann es auf zwei Arten beheben.

Erstens kann ich den NSLog an der Spitze der Funktion auskommentieren. Ich bekomme ein Leck von der NSLog ABRecordCopyValue jedes Mal durch, aber der Code scheint gut zu laufen.

Auch kann ich die

CFRelease(multi); 

am Ende auf Kommentar, die genau dasselbe tun. Statische Kompilierungsfehler, aber laufender Code.

Also ohne ein Leck, stürzt diese Funktion ab. Um einen Unfall zu verhindern, muss ich die Erinnerung bluten. Keine ist eine großartige Lösung.

Kann jemand darauf hinweisen, was vor sich geht?

Antwort

13

Es stellte sich heraus, dass ich die ABRecordRef personDealingWith var nicht richtig gespeichert habe. Ich bin mir immer noch nicht sicher, wie ich das richtig machen soll, aber anstatt die Funktionalität in einer anderen Routine (später ausgeführt) zu haben, mache ich jetzt die Grunt-Arbeit in der Delegate-Methode und verwende die abgeleiteten Ergebnisse in meiner Freizeit. Die neue (funktionierende) Routine:

- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person { 
    // as soon as they select someone, return 
    personDealingWithFullName = (NSString *)ABRecordCopyCompositeName(person); 
    personDealingWithFirstName = (NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty); 
    // construct array of emails 
    [personDealingWithEmails removeAllObjects]; 
    ABMutableMultiValueRef multi = ABRecordCopyValue(person, kABPersonEmailProperty); 
    if (ABMultiValueGetCount(multi) > 0) { 
     // collect all emails in array 
     for (CFIndex i = 0; i < ABMultiValueGetCount(multi); i++) { 
      CFStringRef emailRef = ABMultiValueCopyValueAtIndex(multi, i); 
      [personDealingWithEmails addObject:(NSString *)emailRef]; 
      CFRelease(emailRef); 
     } 
    } 
    CFRelease(multi); 
    return NO; 
} 
0

Ich stieß auf ein ähnliches Problem. Das Problem liegen könnte, wie Sie Ihr Set

ABRecordRef personDealingWith; 

Es scheint, dass man kann nicht einfach tun:

ABRecordRef personDealingWith = person; 

Da personDealingWith null bleibt. Stattdessen was ich tat ist:

ABRecordID personID = ABRecordGetRecordID(person); 
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL); 
personDealingWith = ABAddressBookGetPersonWithRecordID(addressBook, personID);