Как правильно пакетный индекс в центре внимания
Я начинаю использовать Core Spotlight для индексирования элементов в моем приложении. Как я и предполагал, приложение зависает на моем устройстве, но не на симуляторе, потому что у меня есть более 2000 элементов для индексации. Я заметил, что к тому времени, когда я добавляю около 427 элементов в мое NSMutableArray
удерживая мои предметы, и вылетает полностью к тому времени, когда получается 540 предметов.
Я осознаю способность batch
эти индексы, и я могу видеть код, представленный Apple на их сайте Apple - Содержание приложения индекса - Использование расширенных функций. Однако я не уверен, как именно это реализовать.
Может ли кто-нибудь добавить код или указать мне правильное направление для достижения этой цели?
Обновление № 1 (2016/06/21)
Предметы, которые я пытаюсь проиндексировать, включают более 2000 имен, с номерами телефонов, адресами электронной почты, названием и информацией об отделе для моей компании. У меня есть встроенный файл, но я также периодически скачиваю файл, чтобы получить актуальную информацию. Я сохраняю данные как plist
не в CoreData
, После загрузки файла я запускаю индексирование, сначала удаляя все, что в данный момент проиндексировано, а затем добавляя все элементы. С сервера я не могу определить, изменились ли данные.
Моя цель - индексировать около 200-400 элементов одновременно, пока все элементы не будут проиндексированы. Ниже показано, как я сейчас индексирую без пакетирования.
- (void)setupCoreSpotlightSearchFor:(NSString *)fileName {
if ([fileName isEqual:kPlistFileNameEmployee]) {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *downloadFileUrl = kDirectoryEmployeeListDownload;
if ([fileManager fileExistsAtPath:[downloadFileUrl path]]) {
NSArray *dataArray = nil;
NSError *error = nil;
dataArray = [NSArray arrayPropertyListWithURL:downloadFileUrl error:&error];
if (!error && dataArray) {
NSMutableArray *items = nil;
int counter = 0;
for (NSDictionary *person in dataArray) {
NSNumberFormatter *f = [[NSNumberFormatter alloc] init];
f.numberStyle = NSNumberFormatterDecimalStyle;
NSNumber *idNum = [f numberFromString:[[person objectForKey:@"Id"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]];
NSString *firstName = [[person objectForKey:@"FirstName"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *lastName = [[person objectForKey:@"LastName"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *email = [[person objectForKey:@"Email"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *phone = [[person objectForKey:@"Extension"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *title = [[person objectForKey:@"Title"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *organization = [[person objectForKey:@"Organization"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *department = [[person objectForKey:@"Department"] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kCIAttributeTypeImage];
Person *person = [Person createPersonWithId:idNum
FirstName:[NSString stringOrNil:firstName]
LastName:[NSString stringOrNil:lastName]
Email:[NSString stringOrNil:email]
PhoneNumber:[NSString stringOrNil:phone]
Title:[NSString stringOrNil:title]
Organization:[NSString stringOrNil:organization]
Department:[NSString stringOrNil:department]
];
if ([NSString stringOrNil:[person fullName]] != nil) {
[attributeSet setTitle:[person fullName]];
[attributeSet setContentDescription:[person title]];
NSMutableArray *keywords = [[NSMutableArray alloc] init];
if ([NSString stringOrNil:[person firstName]] != nil) {
[keywords addObject:[person firstName]];
}
if ([NSString stringOrNil:[person lastName]] != nil) {
[keywords addObject:[person lastName]];
}
if ([NSString stringOrNil:[person title]] != nil) {
[keywords addObject:[person title]];
}
if ([NSString stringOrNil:[person department]] != nil) {
[keywords addObject:[person department]];
}
if ([NSString stringOrNil:[person phoneNumber]] != nil) {
[keywords addObject:[person phoneNumber]];
}
if ([NSString stringOrNil:[person email]] != nil) {
[keywords addObject:[person email]];
}
[attributeSet setKeywords:keywords];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 180, 180)];
[imageView setImageWithString:[person initialsWithCapitalization:InitialsCapitalizationTypeBoth andLastNameFirst:NO] color:[UIColor colorWithRed:0.77 green:0.07 blue:0.19 alpha:1.0] circular:YES];
[attributeSet setThumbnailData:UIImagePNGRepresentation([imageView image])];
if ([NSString stringOrNil:[person phoneNumber]] != nil) {
[attributeSet setSupportsPhoneCall:[NSNumber numberWithInt:1]];
[attributeSet setPhoneNumbers:@[[person phoneNumber]]];
}
if ([NSString stringOrNil:[person email]] != nil) {
[attributeSet setEmailAddresses:@[[person email]]];
}
CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:[NSString stringWithFormat:@"%@", [person id]] domainIdentifier:@"com.myapp.index.employee" attributeSet:attributeSet];
if (item) {
if (!items) {
items = [[NSMutableArray alloc] init];
}
[items addObject:item];
counter++;
}
}
}
if (items) {
// delete current items
[[CSSearchableIndex defaultSearchableIndex] deleteAllSearchableItemsWithCompletionHandler:^(NSError * _Nullable error) {
if (error) {
DLog(@"%@",error);
} else {
DLog(@"Deleted Index!");
// add new items
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:items completionHandler:^(NSError * _Nullable error) {
if (error) {
DLog(@"%@",error);
} else {
DLog(@"Added Index!");
}
}];
}
}];
}
}
}
}
}
Спасибо!
1 ответ
Таким образом, ваша проблема с памятью на самом деле не имеет ничего общего с центральным освещением, потому что ваш код падает до того, как вы туда попали. Вы должны профиль, чтобы точно проверить, что занимает всю память, я думаю, изображения, которые вы генерируете, являются значительной частью этого, особенно потому, что вы используете данные PNG вместо JPEG (со значительным сжатием, учитывая простую природу изображений), Также кажется очень расточительным создание представления изображения, когда действительно требуется изображение, и вдвойне расточительно создавать новое представление изображения на каждой итерации цикла...
Таким образом, вы не должны на самом деле выполнять пакетную обработку ядра, вы должны обрабатывать свои файлы. Есть несколько способов сделать это, но главное в том, что вы обрабатываете, скажем, 100 элементов из файла в массив, затем передаете это в центр внимания ядра и ждете его завершения. Затем вы запускаете следующие 100 элементов в файле.
Вы можете сделать это с асинхронным NSOperation
, Вы можете сделать это с помощью рекурсивного блока и GCD.