Сократить время на выполнение больших операций в приложении для iPhone - PullRequest
0 голосов
/ 31 марта 2012

Когда я запускаю приложение, мне нужно извлечь все контакты из адресной книги и сохранить их в массиве для отображения в виде таблицы. Я написал этот код в методе 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];
}

Ответы [ 3 ]

1 голос
/ 31 марта 2012

Во-первых, попробуйте некоторые общие подходы, чтобы сократить время, используя более оптимизированный код и меньше повторений кода и также за счет меньшего использования циклов или может быть только итерации цикла только до получения данных .Также вы можете проверить, правильно ли распространяется ваш код в отношении Time Profiling .

Во-вторых, мы считаем, что требуется больше времени, потому что пользователю показывают индикатор активности до 14 секунд.Если вы не показываете его и не блокируете пользовательский интерфейс до тех пор, пока данные не будут скопированы в ваш массив, то пользователь может почувствовать, что он более плавный. Вот как вы можете это сделать:

Вы можетеиспользуйте NSThread, чтобы разрешить запуск приложения, пока вы извлекаете все данные из адресной книги и сохраняете их в своем массиве.

Вы можете использовать

[NSThread detachNewThreadSelector:@selector(fetchAddressContacts:) withObject:nil];

Для получения дополнительной информации вы можете обратиться к detachNewThreadSelector: из 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.
}

Дайте мне знать, если вам нужна дополнительная помощь.

Надеюсь, это поможет вам.

0 голосов
/ 31 марта 2012

При первой установке приложения извлекайте все контакты и сохраняйте их в файле coredate / plist при следующем открытии приложения, затем отображайте контакты из хранилища, что очень быстро по сравнению с извлечением контактов из базы данных iPhone.Теперь проблема, как обновить контакты, которые недавно добавлены, поэтому для каждого контакта есть свойства с именами «kABPersonModificationDateProperty» и «kABPersonCreationDateProperty», используйте это, чтобы найти только обновленные контакты и добавить в хранилище.Надеюсь, это поможет.

0 голосов
/ 31 марта 2012
  1. Выполните диагностику метода поиска контактов и определите, какие вызовы вызывают узкое место здесь.
  2. Поделитесь своим кодом и опишите узкие места

Любая операция, занимающая значительное количество времени, должна выполняться в потоке. В этом случае я собираю данные только при первом запуске и сохраняю их внутри. Вы можете обновить первичные данные в любое время позже по требованию (кнопка обновления?), Иначе работайте с внутренне сохраненным «клоном» контактов, а не вызывайте любую трудоемкую операцию при запуске каждого приложения.

Кстати: будьте осторожны с контактами адресной книги в эти дни: -)

...