Frage

Ich erhalte die E-Mail-Adressen aus dem Adressbuch von Cocoa-Touch-Projekt und immer einige unerwartete Ergebnisse in Bezug auf die Speichernutzung.Der Benutzer öffnet die ABPeoplePicker und wenn die AB den Eintrag, den Sie berühren, hat eine einzige E-Mail-Adresse oder keinen E-Mail-Adresse Sie verwendet

  • (BOOL) peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person

und, falls der Eintrag mehrere E-Mail-Adressen, es bewegt sich auf

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

In der E-Mail-Adresse Fall, den gesamten Speicher verwendet durch die Farbauswahl ist freigegeben, nachdem die E-Mail-Adresse ist ausgewählt.In der zweiten mehrere E-Mail-Fall, über 300k gehalten und nicht freigegeben, und dies erhöht sich jedes mal, wenn ein multi-E-Mail-Adresse-Buch-Eintrag wird gewählt.Ich glaube, dass ich manuell freigegeben werden alles, was ich brauche, um in die Methoden AB und ich kann nicht verfolgen Sie nach unten, was hält Sie auf, dass der Speicher oder wie es zu beheben, und ich bin nicht zu sehen, andere Beiträge über das ein bug, so dass ich vermute, ich habe einen Fehler.Wenn jemand irgendwelche Ideen, was hier Los ist, bitte lassen Sie mich wissen.Ich habe die beigefügte Beispiel-code unten, für diejenigen, die möchten, um das problem zu reproduzieren - es verhält sich identisch im simulator auf dem Gerät, so dass Sie können führen Sie es in die simulator mit Activity Monitor zu sehen, die Speicher-Nutzung.Vielen Dank für jede Unterstützung!

Beide Adressbuch.Rahmen und AddressBookUI.framework Hinzugefügt werden müssen, um ein Projekt diesen code ausführen, damit es funktioniert, und ich bin mit dem 3.0 SDK:

testViewController.h:

#import <UIKit/UIKit.h>
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
@interface testViewController : UIViewController <ABPeoplePickerNavigationControllerDelegate> {
    UITextView *emailList ;
}

@property (nonatomic, retain) UITextView *emailList ;
@end

testViewController.m:

#import "testViewController.h"

@implementation testViewController

@synthesize emailList;

- (void) showContactPicker:(id)sender {

ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[self presentModalViewController:picker animated:YES];
[picker release];
}


- (void) peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker {
[self dismissModalViewControllerAnimated:YES];
}

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

    BOOL returnState = NO;

    ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);

    if(ABMultiValueGetCount(emails) <= 0) { // the selected contact has no attached email address

        [self dismissModalViewControllerAnimated:YES];
    }

    else if(ABMultiValueGetCount(emails) == 1) { // the selected contact has exactly one email address

        CFStringRef email = ABMultiValueCopyValueAtIndex(emails, 0);
        NSString *emailString = (NSString *) email;
        self.emailList.text = [self.emailList.text stringByAppendingString:[NSString stringWithFormat:@"%@ ", emailString]];
        [emailString release];
        [self dismissModalViewControllerAnimated:YES];
    }

    else { // the selected contact has many email addresses, continue to the alternate method
        returnState =  YES;
    }

    CFRelease(emails);
    return returnState;
}




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

    ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);
    CFStringRef multiEmail = ABMultiValueCopyValueAtIndex(multiEmails, identifier);
    CFRelease(multiEmails);
    NSString *multiEmailString = (NSString *) multiEmail;
    //CFRelease(multiEmail); //AnalysisTool pointed out that this is a double release since multiEmailString is an alias of multiEmail
    self.emailList.text = [self.emailList.text stringByAppendingString:[NSString stringWithFormat:@"%@ ", multiEmailString]];
    [multiEmailString release];
    [self dismissModalViewControllerAnimated:YES];
    return NO;
}


- (void)viewDidLoad {
     [super viewDidLoad];

        NSArray *openContactsTitle = [[NSArray alloc] initWithObjects:@"Add Addresses", nil];
        UISegmentedControl *openContacts = [[UISegmentedControl alloc] initWithItems:openContactsTitle];
    openContacts.frame = CGRectMake(10,10,105,30);
    [openContacts addTarget:self action:@selector(showContactPicker:) forControlEvents:UIControlEventValueChanged];
    openContacts.segmentedControlStyle = UISegmentedControlStyleBar;
    openContacts.momentary = TRUE;
    [self.view addSubview:openContacts];
    [openContacts release];
    [openContactsTitle release];

    emailList = [[UITextView alloc] initWithFrame:CGRectMake(10,60,200,200)];
    [self.view addSubview:emailList];
    emailList.text = @"";
}


- (void)dealloc {
    [emailList release];
    [super dealloc];
 }

@end
War es hilfreich?

Lösung

Während der Entwicklung der App " mein iPhone Serial-Mail Ich hatte entdeckt, dass ein Speicherverlust in ABPeoplePickerNavigationController.Ich eingereicht haben dies als ein Fehler auf den Apple Bug Reporter.Feedback von Apple ist, dass er ein bekannter bug (mein bug report ist geschlossen, wie ein Duplikat der ID 6547310).

Andere Tipps

Sie könnten versuchen, ausgeführt AnalysisTool um zu sehen, wenn es kann erkennen Lecks in den code

Eine option ist, um den picker eine readonly-Eigenschaft der Klasse und nicht synthetisieren es.Erstellen Sie stattdessen eine peoplePicker-Methode sicherzustellen, dass nur eine einzelne Instanz der picker wird instanziiert.Wenn das nicht funktioniert mit Ihrem aktuellen view-lifecycle wäre eine option sein, zu abstrahieren, diese in eine eigentliche singleton-Klasse.

Hier ist ein Beispiel, das ich für das Bild verwendet picker (Kamera), die die gleiche Leck problem:

- (UIImagePickerController*)pickerController
{
    // pickerController is a readonly property
    if( pickerController == nil )
    {
        pickerController = [[UIImagePickerController alloc] init];
        pickerController.allowsImageEditing = NO;
    }
    return pickerController;
}

Dafür habe ich alle Versionen in dealloc und didReceiveMemoryWarning (mit einem null-check, um zu vermeiden, die Freigabe nil).In diesem Fall werden Sie wirksam zu begrenzen, wie oft Sie das Adressbuch picker instanziiert wird.In vielen Orten Apple empfiehlt die Verwendung eines singleton-Implementierung für die Speicher-intensive picker-APIs.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top