当我启动应用时,我需要从地址簿中检索所有联系人。将其存储在数组中以在表视图中显示它。我在viewDidAppear方法中编写了这段代码。当联系人从地址簿中检索时,我正在显示活动指示符。我的地址簿中有大约1100个联系人。为此,花费了14秒来检索数据和将其存储在数组中。这是不可接受的时间。所以我需要优化这个&将时间缩短到最多2到3秒。
我需要所有联系人,因为当我的应用程序启动时,我需要搜索联系人,因此我需要我的数组中可用的所有数据。
如何缩短此时间?如果您需要更多信息,请告诉我。 任何形式的帮助都非常感谢。感谢。
更新1:我的代码
- (NSMutableArray*)getAddressBookData {
self.tempArray = [[NSMutableArray alloc]init];
addressBook = ABAddressBookCreate();
APP_DELGATE.people = (NSArray*)ABAddressBookCopyArrayOfAllPeople(addressBook);
peopleCount = [APP_DELGATE.people count];
for (int i=0; i<peopleCount; i++) {
ABRecordRef record = [APP_DELGATE.people objectAtIndex:i];
NSNumber *recordId = [NSNumber numberWithInteger:ABRecordGetRecordID(record)];
NSLog(@"record id is %@",recordId);
// Get fname, lname, company
NSString *fnm = (NSString *)ABRecordCopyValue(record, kABPersonFirstNameProperty) ;
NSString *lnm = (NSString *)ABRecordCopyValue(record, kABPersonLastNameProperty) ;
NSString *comp = (NSString*)ABRecordCopyValue(record,kABPersonOrganizationProperty);
// Get Ph no
ABMultiValueRef phoneNumberProperty = ABRecordCopyValue(record, kABPersonPhoneProperty);
NSArray* phoneNumbers = [self getPhoneNoWithoutSymbols:(NSArray*)ABMultiValueCopyArrayOfAllValues(phoneNumberProperty)];
NSString *strPhoneNos = [self getStringRepresentaionFromArray:phoneNumbers];
NSLog(@"strPhoneNos => %@",strPhoneNos);
// Get emails
ABMultiValueRef emailProperty = ABRecordCopyValue(record, kABPersonEmailProperty);
NSArray* emails = (NSArray*)ABMultiValueCopyArrayOfAllValues(emailProperty);
NSString *strEmails = [self getStringRepresentaionFromArray:emails];
NSLog(@"strEmails => %@",strEmails);
// Get URL
ABMultiValueRef urlProperty = ABRecordCopyValue(record, kABPersonURLProperty);
NSArray* urls = (NSArray*)ABMultiValueCopyArrayOfAllValues(urlProperty);
NSString *strURLs = [self getStringRepresentaionFromArray:urls];
NSLog(@"strURLs => %@",strURLs);
// Get Address
ABMultiValueRef address=ABRecordCopyValue(record, kABPersonAddressProperty);
CFDictionaryRef dic=nil;
NSMutableArray *addressArray = [[NSMutableArray alloc]init];
for (int index=0; index<ABMultiValueGetCount(address); index++) {
dic=ABMultiValueCopyValueAtIndex(address, index);
NSString* labelName=(NSString*)ABMultiValueCopyLabelAtIndex(address, index);
if (labelName) {
NSString *street =(NSString*) CFDictionaryGetValue(dic, kABPersonAddressStreetKey);
NSString *city= (NSString*)CFDictionaryGetValue(dic, kABPersonAddressCityKey) ;
NSString *state= CFDictionaryGetValue(dic, kABPersonAddressStateKey);
NSString *country=CFDictionaryGetValue(dic, kABPersonAddressCountryKey);
NSString *zipcode=CFDictionaryGetValue(dic, kABPersonAddressZIPKey);
NSString *addressDetails=@"";
if (street) {
addressDetails=[NSString stringWithFormat:@"%@ ",street];
}
if (city) {
addressDetails=[NSString stringWithFormat:@"%@ %@ ",addressDetails,city];
}
if (state) {
addressDetails=[NSString stringWithFormat:@"%@ %@ ",addressDetails,state];
}
if (country) {
addressDetails=[NSString stringWithFormat:@"%@ %@ ",addressDetails,country];
}
if (zipcode) {
addressDetails=[NSString stringWithFormat:@"%@ %@ ",addressDetails,zipcode];
}
[addressArray addObject:addressDetails];
}
}
NSString *strAddress = [self getStringRepresentaionFromArray:addressArray];
NSLog(@"strAddress => %@",strAddress);
// Get Notes
NSString *noteString=(NSString *)ABRecordCopyValue(record, kABPersonNoteProperty);
// Get Birthdate
NSDate *birthDate=(NSDate*)ABRecordCopyValue(record, kABPersonBirthdayProperty) ;
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"MMMM dd yyyy"];
NSString *birthdateString = [formatter stringFromDate:birthDate];
[formatter release];
// Get user image
UIImage *image = nil;
if( ABPersonHasImageData( record ) ) {
NSData *imageData = (NSData*)ABPersonCopyImageData(record);
image = [UIImage imageWithData:imageData];
[imageData release];
}
// Create User object & add it to array
User *user = [[User alloc]initUserWithUniqID:recordId.intValue FirstName:fnm lastName:lnm company:comp phoneNumbers:strPhoneNos emails:strEmails urls:strURLs address:strAddress notes:noteString dob:birthdateString userImage:image];
[self.tempArray addObject:user];
[user release];
}
self.tempArray = [NSMutableArray arrayWithArray:[self.tempArray sortedArrayUsingSelector:@selector(compare:)]];
APP_DELGATE.allUsersArray = self.tempArray;
return tempArray;
}
-(NSMutableArray*)getPhoneNoWithoutSymbols:(NSArray*)array {
self.phNoArray = [[NSMutableArray alloc]init];
for (NSString *str in array) {
[self.phNoArray addObject:[self getPhNo:str]];
}
return self.phNoArray;
}
-(NSString*)getPhNo:(NSString*)str {
NSString *str0 = [str stringByReplacingOccurrencesOfString:@" " withString:@""];
NSString *str1 = [str0 stringByReplacingOccurrencesOfString:@"(" withString:@""];
NSString *str2 = [str1 stringByReplacingOccurrencesOfString:@")" withString:@""];
NSString *str3 = [str2 stringByReplacingOccurrencesOfString:@"-" withString:@""];
return str3;
}
-(NSString*)getStringRepresentaionFromArray:(NSArray*)array {
return [array componentsJoinedByString:DELIMITER_SYMBOL];
}
答案 0 :(得分:1)
首先,尝试一些通用的方法,通过使用更优化的代码和减少重复代码来减少时间,并且也可以通过减少使用循环或者可能仅迭代循环,直到获得数据。此外,您还可以检查代码是否正确分布到时间分析。
其次,我们认为所需时间更长,因为用户会在14秒后显示活动指示。如果您没有显示它并且在数据被复制到您的阵列之前不阻止用户界面,那么用户可能会觉得它更加流畅所以这就是您如何做到这一点:
您可以使用NSThread
来启动应用程序,同时从AddressBook检索所有数据并将其存储在阵列中。
您可以使用
[NSThread detachNewThreadSelector:@selector(fetchAddressContacts:) withObject:nil];
有关详细信息,请参阅detachNewThreadSelector: from NSThread
所以基本上在AppDelegate
中,您需要在AppDelegate.m
-(void)applicationDidFinishLaunching:(UIApplication *)application {
[NSThread detachNewThreadSelector:@selector(fetchAddressContacts) withObject:nil];
}
-(void)fetchAddressContacts {
//Do your stuff to copy your contacts from address book to array
// Once you finish this task you can trigger an NSNotification which could be caught on some other viewController or implement a delegate to transfer data to a viewController and proper actions can be executed once the data is loaded.
}
如果您需要更多帮助,请与我联系。
希望这会对你有所帮助。
答案 1 :(得分:0)
任何花费大量时间的操作都应该在一个线程中执行。在这种情况下,我只在第一次启动时收集数据并在内部存储它们。您可以随时根据需要刷新主数据(刷新按钮?),否则可以使用联系人内部存储的“克隆”,而不是在每个应用程序启动时调用任何耗时的操作。
顺便说一句:这些天要小心通讯录联系人: - )
答案 2 :(得分:0)
当您的应用首次安装时,会在下次应用程序打开时获取所有联系人并保存在coredate / plist文件中,然后显示来自存储的联系人,这与从iPhone数据库中提取联系人相比非常快。现在问题是如何更新新添加的联系人,因此对于每个联系人都有一个名为“kABPersonModificationDateProperty”和“kABPersonCreationDateProperty”的属性,使用它来查找更新的联系人并添加到存储中。希望这会有所帮助。