NSRunLoop основного потока, ссылаемый во вторичном потоке

Вы также можете отсортировать ArrayCollection по Criteria свойству orderBy следующим образом:

<?php
    namespace App/Service;

    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Criteria;

    /**
     * Class SortService
     *
     * @package App\Service
     */
    class SortService {
        /**
         * @param SomeAbstractObject $object
         * @return SomeCollectionItem[]
         */
        public function sorted(SomeAbstractObject $object): array {
            /** $var ArrayCollection|SomeCollectionItem[] */
            $collection = $object->getCollection();

            // convert normal array to array collection object
            if(\is_array(collection)) {
                $collection = new ArrayCollection(collection);
            }

            // order collection items by position property
            $orderBy = (Criteria::create())->orderBy([
                'position' => Criteria::ASC,
            ]);

            // return sorter SomeCollectionItem array
            return $collection->matching($orderBy)->toArray();
        }
    }
?>
5
задан Girish 27 May 2013 в 10:58
поделиться

3 ответа

Отвечая на ваши вопросы в обратном порядке:

2 . У тебя две проблемы. В документации для - [NSRunLoop run] говорится:

Если нет источников ввода или таймеров прикрепленный к циклу выполнения, этот метод немедленно выходит; в противном случае он работает приемник в NSDefaultRunLoopMode многократно вызов runMode: beforeDate: . В других словами, этот метод эффективно начинается бесконечный цикл, который обрабатывает данные из источников ввода цикла выполнения и таймеры.

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

Для того, чтобы все работало правильно, ваш цикл выполнения должен сначала иметь некоторые источники ввода, а затем необходимо периодически запускать для проверки событий. Обратите внимание, что вы не хотите использовать [NSRunLoop run] , так как вы никогда не вернете контроль. Вместо этого я бы рекомендовал настроить цикл прямо перед тем, как вернет YES , который непрерывно запускает цикл выполнения до тех пор, пока поток не будет отменен или пока вы не закончите потоковую передачу данных. Это позволит циклу выполнения обрабатывать данные по мере их поступления. Примерно так:

while (!done) {
    [myRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
}

[NSRunLoop runUntilDate:] обрабатывает события до указанной даты, а затем возвращает управление вашей программе, чтобы вы могли делать все, что захотите.

1 . Это работает, потому что цикл выполнения вашего основного потока запускается периодически, поэтому события обрабатываются. Однако, если ваш основной поток когда-либо заблокируется, ваши данные перестанут поступать. Это может быть особенно плохо, если основной поток ждал данных от вашего второго потока. Кроме того, NSRunLoop не является потокобезопасным:

Предупреждение: класс NSRunLoop является обычно не считается потокобезопасный и его методы должны только в контексте текущий поток. Вы никогда не должны попробуйте вызвать методы Объект NSRunLoop, работающий в другой поток, так как это может вызвать неожиданные результаты. (из документации NSRunLoop.)

В Руководстве по программированию потоков Apple есть раздел под названием Run Loop Management , который в некоторой степени объясняет все это. Это не самый ясный документ, который я когда-либо читал, но если вы работаете с циклами выполнения, это хорошее место для начала.

6
ответ дан 14 December 2019 в 01:16
поделиться

Вы не забыли запустить цикл выполнения?

[[NSRunLoop currentLoop] run]
2
ответ дан 14 December 2019 в 01:16
поделиться

Во-первых, планировщик ... должен автоматически добавлять таймер в текущий цикл выполнения. Вам нужно использовать метод addTimer: , только если вы создали таймер с помощью initWithFireDate ... инициализатор. Я сомневаюсь, что добавление таймера дважды вызовет проблему, но это возможно.

Предполагается, что метод run для NSRunLoop не должен возвращаться, пока не будет больше источников событий или пока цикл не будет явно завершен. Это означает, что вам необходимо запланировать все источники событий до того, как вызовет run . Переместите вызов [myRunLoop run] в самый конец образца кода. (Также, очевидно, исключите оператор return )

Суть в том, что если [NSRunLoop run] возвращается, значит, у вас нет запланированного источника события . Используйте отладчик для пошагового выполнения кода. Если вы видите, что он прогрессирует после вызова [NSRunLoop run] , вы можете быть уверены, что у вас проблема с источниками входного сигнала.

Это означает, что вам необходимо запланировать все источники событий до того, как вызовет run . Переместите вызов [myRunLoop run] в самый конец образца кода. (Также, очевидно, исключите оператор return )

Суть в том, что если [NSRunLoop run] возвращается, значит, у вас нет запланированного источника события . Используйте отладчик для пошагового выполнения кода. Если вы видите, что он прогрессирует после вызова [NSRunLoop run] , вы можете быть уверены, что у вас проблема с источниками входного сигнала.

Это означает, что вам необходимо запланировать все источники событий до того, как вызовет run . Переместите вызов [myRunLoop run] в самый конец образца кода. (Также, очевидно, исключите оператор return )

Суть в том, что если [NSRunLoop run] возвращается, значит, у вас нет запланированного источника события . Используйте отладчик для пошагового выполнения кода. Если вы видите, что он прогрессирует после вызова [NSRunLoop run] , вы можете быть уверены, что у вас проблема с источниками входного сигнала.

На нем запланирован источник событий. Используйте отладчик для пошагового выполнения кода. Если вы видите, что он прогрессирует после вызова [NSRunLoop run] , вы можете быть уверены, что у вас проблема с источниками входного сигнала.

На нем запланирован источник событий. Используйте отладчик для пошагового выполнения кода. Если вы видите, что он прогрессирует после вызова [NSRunLoop run] , вы можете быть уверены, что у вас проблема с источниками входного сигнала.

1
ответ дан 14 December 2019 в 01:16
поделиться