Используя представления эффективно

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

Будьте непрозрачны

При реализации пользовательского подкласса NSView можно ускорить производительность получения путем объявления объекта представления как непрозрачного. Непрозрачное представление является тем, заполняющим его весь ограничительный прямоугольник содержанием. Система рисования Какао не отправляет сообщения обновления в суперпредставление для областей, покрытых одним или более непрозрачными подпредставлениями.

isOpaque метод возвратов NSView NO по умолчанию. Для объявления пользовательского объекта представления как непрозрачного переопределите этот метод и возврат YES. При создании непрозрачного представления помните, что объект представления ответственен за заполнение его ограничительного прямоугольника с содержанием.

Нарисуйте минимально

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

Рисование содержания

Несмотря на то, что проверка Вашего содержания против ограничительного прямоугольника передала в drawRect: хорошее начало, Какао действительно обеспечивает дополнительные методы для определения что потребности быть перерисованным. Доступность этих методов зависит от рабочей версии OS X, хотя, таким образом, Вы, возможно, должны были бы проверить для проверки, метод доступен прежде, чем попытаться использовать его.

В версии 10.3 OS X и позже, приложения Какао имеют два способа получить более усовершенствованную версию прямоугольника получения. Прямоугольник передается в NSView drawRect: метод формируется путем создания объединения всех грязных прямоугольников. Однако, если обновленные области являются маленькими и далеко друг от друга, область объединения может часто быть намного больше и содержать много неизменного содержания. Вместо того, чтобы использовать этот прямоугольник, можно вместо этого вызвать представление getRectsBeingDrawn:count: метод, чтобы получить массив отдельных прямоугольников обновления и использовать NSIntersectsRect функция для сравнения их с ограничительным прямоугольником объекта. Еще более простой способ сделать это должно вызвать needsToDrawRect: метод, выполняющий оба из этих шагов для Вас.

Следующий пример показывает простое drawRect: метод, рисующий объекты в пользовательском представлении. В этом примере класс MyDrawableThing не убывает от NSView, но вместо этого определяет объект с помощью ограничительного прямоугольника и некоторого содержания, которое знает представление, как нарисовать.

- (void) drawRect:(NSRect)aRect
{
    NSEnumerator* myEnumerator = [myArray objectEnumerator];
    MyDrawableThing* currentThing;
 
    while (currentThing = [myEnumerator nextObject])
    {
        // Draw the thing if it is in one of the update rectangles.
        if ([self needsToDrawRect:[currentThing bounds]])
        {
            [self drawThing:currentThing];
        }
    }
}

Можно использовать Кварцевый Отладчик для наблюдения, где приложение рисует и найти области, где это рисует содержание избыточно. Для получения дополнительной информации см. “Измеряющую Производительность Получения” в Рисовании Инструкций по Производительности.

Лишение законной силы частей представления

Какао обеспечивает два метода для перерисовки содержания Ваших представлений. Первый метод должен сразу нарисовать содержание с помощью display, displayRect:, или связанные методы. Второе должно нарисовать содержание в более позднее время путем маркировки частей представления как грязных и нуждающихся в обновлении. Этот второй метод предлагает значительно лучшую производительность и является подходящим для большинства ситуаций.

NSView определяет методы setNeedsDisplay: и setNeedsDisplayInRect: для маркировки частей Вашего представления как грязное. Какао собирает грязные прямоугольники и сохраняет их, пока вершина Вашего цикла выполнения не достигнута, в которой точке Вашему представлению говорят перерисовать себя. Прямоугольник передал в Ваш drawRect: подпрограмма является объединением грязных прямоугольников, но приложения, работающие на версии 10.3 OS X и позже, могут получить список отдельных прямоугольников, как описано в Рисовании Содержания.

В целом необходимо избежать вызывать display семья методов для перерисовки представлений. Если необходимо вызвать их, делайте так нечасто. Поскольку они вызывают непосредственный вызов к Вашему drawRect: подпрограмма, они могут заставить производительность замедляться значительно путем вытеснения других незаконченных операций. Они также устраняют возможность объединить другие изменения и затем перерисовать те изменения одновременно.

Избегите злоупотребления представлениями

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

Несмотря на то, что окна Cocoa могут управлять относительно большим количеством представлений (приблизительно сто), не перенося производительность значимые проблемы, это число включает и Ваши пользовательские представления и стандартные системные средства управления и подпросматривает Вас использование. Если Ваше окно имеет сотни пользовательских визуальных элементов, Вы, вероятно, не хотите реализовывать их всех как подклассы NSView. Вместо этого необходимо рассмотреть запись собственных классов, которыми может управлять высокоуровневый подкласс NSView. Код для прорисовки Вашего подкласса NSView может тогда быть оптимизирован для обработки пользовательских объектов.

Хорошим примером того, когда использовать пользовательские объекты, является браузер фотографий, выводящий на экран изображения миниатюр сотен или даже тысячи фотографий. Обертывание каждой фотографии в NSView и было бы предельно дорогим и неэффективным. Вместо этого Вы были бы более обеспечены путем создания легкого класса для управления одной или более фотографиями и пользовательским представлением для управления тем легким классом.