减少在iphone应用上执行大操作的时间
当我启动应用程序时,我需要检索地址簿中的所有联系人&将其存储在数组中以在表格视图中显示它。我在viewDidAppear方法中编写了这段代码。当联系人正在从地址簿中检索时,我正在显示活动指示器。我的地址簿中有大约1100个联系人。为此,花费14秒钟检索数据&将其存储在数组中。这是不可接受的时间。所以我需要优化这个减少时间到最多2到3秒。减少在iphone应用上执行大操作的时间
我需要所有的联系人,因为当我的应用程序启动时,我需要搜索联系人,所以我需要我的数组中可用的所有数据。
如何减少此时间?如果您需要更多信息,请告诉我。 高度赞赏任何形式的帮助。谢谢。
更新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 *[email protected]"";
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];
}
- 执行您的联系人检索方法诊断和确定哪些电话在这里造成的瓶颈。
- 分享您的代码,并描述了瓶颈
任何操作应采取在一个线程中执行的时间严重金额。在这种情况下,我只会在首次启动时收集数据并将其存储在内部。您可以随时根据需要刷新主要数据(刷新按钮?),否则使用内部存储的联系人“克隆”,而不是在每个应用程序的启动时调用任何耗时的操作。
BTW:小心与地址簿中的联系人,这些天:-)
首先,尝试一些通用的方法,通过使用更优化的代码和的代码少重复和还通过更少的减少时间使用循环或可能是只迭代循环,直到获得数据。您还可以检查您的代码是否正确分发,就时间分析而言。
其次,我们觉得所需的时间更多,因为用户显示一个活动指示器,直到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.
}
让我知道,如果你需要更多的帮助。
希望这可以帮助你。
我编辑了我的答案。请参考它。 – 2012-04-01 14:28:51
如果我使用detachNewThreadSelector,我的应用程序启动,然后直到数据载入表视图 – iOSAppDev 2012-04-02 09:21:47
@appDev用户无法看到任何东西:一旦你加载的tableView,则可以显示MBPorgressHUD呈现出“加载数据。”在其标题。直到你的数据加载。通过这种方式,用户可以获知应用程序尚未挂起并正在继续前进。 – 2012-04-02 09:26:49
当你的应用第一次安装获取所有的联系人,并保存在coredate/plist文件时,下一次打开应用程序,然后从显示这是非常快,比较取出由iPhone数据库中的联系人存储的联系人。现在的问题是如何更新新添加的联系人,因此每个联系人都有名为“kABPersonModificationDateProperty”和“kABPersonCreationDateProperty”的属性,使用它仅查找更新的联系人并添加到存储中。希望这可以帮助。
我的建议是获取批量和辅助线程(使用dispatch_async)接触,然后当他们被提取,更新的tableView当主线程的代码返回。您可以添加一个小的加载图标,以便用户知道完整的地址簿何时加载 – justin 2012-03-31 16:45:22
感谢您的回复。你能否详细说明“批量获取联系人”,因为如果我获取20条记录(例如)如何执行搜索?目前我的搜索查询只能对付20条记录。纠正他们,如果我错了。 – iOSAppDev 2012-03-31 16:57:54
请显示您用于将地址簿中的数据加载到数组中的代码。也许一些缓存机制可以用来减少后续启动应用程序的启动时间。 Slev的建议也很好。如果您加载批量,确实只能执行搜索加载到内存中的部分,但它可以为用户提供更好的体验。 – 2012-03-31 18:00:41