Как остановить NSInvocationOperation?

Необходимо учитывать две вещи:

  • По умолчанию, когда в запросе содержится несколько терминов, результаты будут включать документы, соответствующие любому из термины, а не все терминов.
  • По умолчанию ваши запросы будут анализироваться с использованием того же анализатора, который вы использовали при индексации.

Это, в частности, означает, что ваш запрос "Lychee" будет проанализирован на что-то вроде "L Ly Lyc Lych Lyche Lychee" (из-за фильтра ngram ребра). Строка "Apache Strawberry Club Large" была предварительно проанализирована, а термин "Large" был расширен до "L La Lar Larg Large" из-за фильтра граничной диаграммы. Таким образом, запрос «Lychee» будет соответствовать «Apache Strawberry Club Large», просто потому, что они оба содержат слово, начинающееся с L ...

1113 Это явно нежелательное поведение.

Первым шагом было бы изменение способа анализа вашего запроса, чтобы в конечном итоге вы не совпали с совершенно не связанными документами. По сути, вам нужно определить другой анализатор, который почти идентичен, но не имеет фильтра "edge ngram". Затем вам нужно будет указать Hibernate Search использовать этот анализатор для анализа вашего запроса.

См. этот ответ для подробного объяснения.

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

Заменить это:

Query lucenQuery = qb.keyword().onField("name").matching(searchTerm).createQuery();

На это:

Query lucenQuery = qb.simpleQueryString().onField("name").withAndAsDefaultOperator().matching(searchTerm).createQuery();

Ключом является вызов .withAndAsDefaultOperator().

Это изменение будет иметь несколько других эффектов, таких как включение специального синтаксиса во входной строке, поэтому я рекомендую вам прочитать справочную документацию, чтобы точно знать, что такое simpleQueryString.

9
задан Earl Claridad 18 April 2009 в 06:10
поделиться

4 ответа

Это зависит от реализации вашего объекта NSOperation , чтобы фактически остановить что он делает, очистить и выйти, когда получит уведомление об отмене. Сообщения, которые вы хотите отменить все операции в очереди, приведут к тому, что очередь прекратит очередь из новых запущенных операций и отправит сообщение об отмене любым операциям, выполняющимся в настоящее время.

В основном методе вашей операции вы должны проверить isCancelled и обрабатывает это состояние, когда вы фактически отменены.

Для получения дополнительной информации см. Создание и управление объектами операций в Руководстве по программированию потоков.

3
ответ дан 4 December 2019 в 08:02
поделиться

Пост выше - это здорово, но для более прямого ответа на оригинальный вопрос: кажется, что вы не можете остановить объект NSInvocationOperation, потому что он не ' Поддержка отмены. Тебе придется создать подкласс.

5
ответ дан 4 December 2019 в 08:02
поделиться

ОБНОВЛЕНИЕ: Инструменты показывают много утечек, когда я это делаю. Действуйте осторожно! Я сохраняю это здесь на случай, если я действительно что-то пойму, и кто-то еще сможет придумать, как преодолеть препятствие утечки.

Вот извращенная идея, которую я m повторяя попытку, набирая это:

Задайте операцию как объект для метода NSInvocationOperation initWithTarget: selector: object: . Предполагая, что у вас уже есть NSOperationQueue (мы назовем ее очередью ):

NSInvocationOperation *operation = [NSInvocationOperation alloc];
operation = [operation initWithTarget:self selector:@selector(myOperation:) object:operation];
[queue addOperation:operation];
[operation release];

Обратите внимание, что мы должны разбить выделение на отдельный вызов. В противном случае мы не сможем установить объект в операцию !

Затем, в рамках вашего метода операции, верните объект и проведите проверки для isCancelled по желанию. Например:

  - (void)myOperation:(id)object {
    NSInvocationOperation *operation = (NSInvocationOperation *)object;
    if ([operation isCancelled]) return;
    ...
  }

Убедитесь, что ваш селектор заканчивается двоеточием обратно в initWithTarget: ... вызовите, так как вы сейчас будете передавать объект.

Пока все хорошо. Теперь, если я могу заставить cancelAllOperations , я буду знать, действительно ли это работает. :)

  - (void)myOperation:(id)object {
    NSInvocationOperation *operation = (NSInvocationOperation *)object;
    if ([operation isCancelled]) return;
    ...
  }

Убедитесь, что ваш селектор заканчивается двоеточием обратно в initWithTarget: ... вызовите, так как вы сейчас будете передавать объект.

Пока все хорошо. Теперь, если я могу заставить cancelAllOperations , я буду знать, действительно ли это работает. :)

  - (void)myOperation:(id)object {
    NSInvocationOperation *operation = (NSInvocationOperation *)object;
    if ([operation isCancelled]) return;
    ...
  }

Убедитесь, что ваш селектор заканчивается двоеточием обратно в initWithTarget: ... вызовите, так как вы сейчас будете передавать объект.

Пока все хорошо. Теперь, если я могу заставить cancelAllOperations , я буду знать, действительно ли это работает. :)

11
ответ дан 4 December 2019 в 08:02
поделиться

Вам нужно проверить, имеет ли NSInvocationOperation isCancelled значение YES. Для этого в NSInvocationOperation можно использовать Key Value Observing:

Добавить свой объект в качестве наблюдателя NSInvocationOperation isCancelled при выполнении операции:

NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:<targetObj> selector:@selector(<targetMethod>) object:nil];
[operation addObserver:<targetObj> forKeyPath:@"isCancelled" options:NSKeyValueObservingOptionNew context:nil];
[operQueue addOperation:operation];
[operation release];

Затем в targetObj реализовать

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;

наблюдение за тем, чтобы isCancelled был изменен отменой всех операций NSOperationQueue. Вы можете установить здесь частный флаг, а targetMethod может проверить его и отменить при необходимости.

8
ответ дан 4 December 2019 в 08:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: