地址簿选择器的存储器的使用现在iPhone3.0项目
-
05-07-2019 - |
题
我收到电子邮件地址的地址簿从可可触摸的项目,并得到了一些意想不到的结果在存储器的使用。用户打开ABPeoplePicker如果AB进入他们触及具有一个单一的电子邮件地址或没有电子邮件地址它使用
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)人
如果该条目的有多个电子邮件地址它移到
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController*)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)个人财产:(ABPropertyID)酒店的标识:(ABMultiValueIdentifier)标识{
在单一的电子邮件地址的情况下,所有的记忆使用由选择器被释放后的电子邮件地址的选择。在第二个多个电子邮件的情况下,大约300是保持和不释放,这增加了每次一个多的电子邮件地址簿条目的选择。我认为,我必须手动发布的一切,我需要在AB方法与我无法追踪是什么保持在这一存储器或如何解决它,并且我看不到任何其他员额有关,这是一个错误,所以我怀疑我有一个错误。如果任何人有任何想法什么会在这里,请让我知道。我已经连接例代码下面的那些人的愿望的重现的问题,它的行为相同的模拟器上装置这样可以运行的模拟活动的监视器看到存储器的使用。谢谢你任何帮助!
两个通讯录。框架和AddressBookUI.框架需要增加一个项目,运行这个代码,以便为它的功能和我使用的SDK3.0:
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
解决方案
在开发的我的iPhone应用程序 串邮件 我发现了一个存储器泄漏ABPeoplePickerNavigationController.我提出这样一个错误的苹果的错误的记者。反馈,从苹果是他的一个已知的错误(我的错误报告合为一个重复的ID6547310).
其他提示
你可以试试运行 AnalysisTool 就可以看到,如果它可以检测任何泄漏的代码
一种选择是为了使该选择器只读财产的类和不合。相反,创建一个peoplePicker方法,确保只有一个单一实例的选择器是实例化。如果这不起作用你的前景的生命周期的一个选择是将抽象的这种成一个实际的单独类。
这里有一个例子,我用的图像选择器(照相机)具有相同的泄漏的问题:
- (UIImagePickerController*)pickerController
{
// pickerController is a readonly property
if( pickerController == nil )
{
pickerController = [[UIImagePickerController alloc] init];
pickerController.allowsImageEditing = NO;
}
return pickerController;
}
为此,我放所有版本在dealloc和didReceiveMemoryWarning(与"无"检查,以避免释放的无)。在这种情况下,你将有效地限制如何通常的地址簿器是实例化。在许多地方苹果建议使用一个单独的实现存密集型选择器Api。