Усовершенствованные методы получения

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

Добавление теней к нарисованным путям

Какао предоставляет поддержку для теней через NSShadow класс. Имитаторы тени источник света набрал объект, делающие пути, появляются, как будто они плавают выше поверхности представления. Рисунок 6-1 показывает эффект, создаваемый тенью для нескольких путей.

  Тени рисунка 6-1 брошены представленными путями
Shadows cast by rendered paths

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

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

Для создания тени Вы создаете NSShadow возразите и вызовите его методы для установки желаемых теневых атрибутов. При предупреждении одного или более путей, перекрывающих друг друга, несомненно, необходимо будет выбрать цвет, имеющий альфа-значение; иначе, тени, пересекающие другие объекты, могли бы выглядеть плоскими и разрушить эффект. Для применения тени вызовите set метод.

Перечисление 6-1 показывает, что код раньше создавал тень для путей на рисунке 6-1. Частично прозрачный цвет используется для обеспечения наложения путей и теней.

Перечисление 6-1  , Добавляющее тень к пути

[NSGraphicsContext saveGraphicsState];
 
// Create the shadow below and to the right of the shape.
NSShadow* theShadow = [[NSShadow alloc] init];
[theShadow setShadowOffset:NSMakeSize(10.0, -10.0)];
[theShadow setShadowBlurRadius:3.0];
 
// Use a partially transparent color for shapes that overlap.
[theShadow setShadowColor:[[NSColor blackColor]
             colorWithAlphaComponent:0.3]];
 
[theShadow set];
 
// Draw your custom content here. Anything you draw
// automatically has the shadow effect applied to it.
 
[NSGraphicsContext restoreGraphicsState];
[theShadow release];

Эффекты тени сохранены как часть состояния графики, поэтому когда-то установлены, они влияют на все последующие команды рендеринга в текущем контексте. Это - важная вещь помнить, потому что она могла бы вынудить Вас думать о порядке, в котором Вы рисуете свое содержание. Например, если Вы устанавливаете тень, заполняете путь, и затем перечеркиваете тот же путь, Вы не получаете единственную форму со схемой, цветом заливки и тенью. Вместо этого Вы получаете две формы — схему и форму заливки — и две тени, один для каждой формы. При перечеркивании пути после заполнения его тень для перечеркиваемого пути появляется поверх заполненной формы. На рисунке 6-1 желаемый эффект был достигнут путем применения тени к только форме заливки каждого пути.

Создание заливок градиента

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

Рисунок 6-2 показывает некоторые простые узоры заливки градиента. В то время как градиенты c и d показывают радиальные градиенты, градиенты a и b показывают линейные градиенты, заполняющие различные формы Безье и выровненный вдоль различных углов. В случае градиента c, градиент был установлен нарисовать прежде и после стартовых и конечных расположений градиента, таким образом создав и белый круг в самом центре градиента и черную границу, окружающую градиент. Для градиента d, центральные точки кругов, используемых для рисования градиента, смещаются, создавая различный вид эффекта затенения.

  Различные типы рисунка 6-2 градиентов
Different types of gradients

В OS X v10.5 и позже, Какао предоставляет поддержку для рисования градиентов с помощью NSGradient класс. Если Ваше программное обеспечение работает на более ранних версиях OS X, необходимо использовать Кварц или Базовое Изображение для выполнения заливок градиента.

Используя класс NSGradient

В OS X v10.5 и позже, можно использовать NSGradient класс для создания сложных узоров заливки градиента, не имея необходимость писать собственную цветную функцию вычисления. Объекты градиента являются неизменными объектами, хранящими информацию о цветах в градиенте и обеспечивающими интерфейс для рисования тех цветов к текущему контексту. Когда Вы создаете NSGradient объект, Вы указываете один или больше NSColor объекты и ряд дополнительных параметров положения. Во время получения объект градиента использует эту информацию для вычислений цветовых переходов для градиента.

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

Конфигурирование цветов объекта градиента

NSGradient класс использует цветные остановки для определения позиции цветных изменений в ее заливке градиента. Цветная остановка является комбинацией NSColor возразите и число с плавающей точкой в диапазоне 0.0 к 1,0. Число с плавающей точкой представляет относительную позицию связанного цвета вдоль оси получения градиента, который может быть или радиальным или осевым.

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

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

Несмотря на то, что Вы не можете изменить цвета объекта градиента после инициализации его можно получить информацию о цветах, он содержит методы доступа использования. numberOfColorStops метод возвращает число цветов что использование градиента для рисования себя и getColor:location:atIndex: метод получает цветную информацию об остановке для каждого из тех цветов. Если бы Вы хотите знать, какой цвет был бы нарисован для градиента промежуточные две цветных остановки, можно использовать interpolatedColorAtLocation: метод для получения его.

Рисование к высокоуровневому пути

NSGradient класс определяет несколько удобных методов для рисования и радиальные и осевые градиенты:

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

Перечисление 6-2 показывает некоторый код, рисующий осевой образец градиента. NSBezierPath объект, содержащий скругленный прямоугольник, формирует действия как область отсечения для градиента, когда это нарисовано. Рисунок 6-3 показывает итоговый градиент.

Перечисление 6-2  , Отсекающее осевой градиент к скругленному прямоугольнику

- (void)drawRect:(NSRect)rect
{
    NSRect        bounds = [self bounds];
 
    NSBezierPath*    clipShape = [NSBezierPath bezierPath];
    [clipShape appendBezierPathWithRoundedRect:bounds xRadius:40 yRadius:30];
 
 
    NSGradient* aGradient = [[[NSGradient alloc]
                    initWithColorsAndLocations:[NSColor redColor], (CGFloat)0.0,
                                            [NSColor orangeColor], (CGFloat)0.166,
                                            [NSColor yellowColor], (CGFloat)0.33,
                                            [NSColor greenColor], (CGFloat)0.5,
                                            [NSColor blueColor], (CGFloat)0.75,
                                            [NSColor purpleColor], (CGFloat)1.0,
                                            nil] autorelease];
 
    [aGradient drawInBezierPath:clipShape angle:0.0];
}
Рисунок 6-3  Осевой градиент, нарисованный в пути Безье
Axial gradient drawn inside a Bezier path

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

В дополнение к высокоуровневым удобным методам, NSGradient класс определяет два примитивных метода для рисования градиентов:

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

Перечисление 6-3 показывает код для рисования радиального градиента в представлении с помощью примитивной подпрограммы получения NSGradient. Второй круг в градиенте смещается от первого 60 точками и в горизонтальных и в вертикальных направлениях, заставляя полный градиент скоситься к верхнему правому из круга. Поскольку код передает значение 0 для options параметр, градиент не рисует вне запуска и конечных цветов и поэтому не заполняет все представление. Рисунок 6-4 показывает градиент, следующий из этого кода.

Перечисление 6-3  , Получающее радиальный градиент с помощью примитивной подпрограммы

- (void)drawRect:(NSRect)rect
{
    NSRect bounds = [self bounds];
    NSGradient* aGradient = [[[NSGradient alloc]
                                    initWithStartingColor:[NSColor orangeColor]
                                    endingColor:[NSColor cyanColor]] autorelease];
 
    NSPoint centerPoint = NSMakePoint(NSMidX(bounds), NSMidY(bounds));
    NSPoint otherPoint = NSMakePoint(centerPoint.x + 60.0, centerPoint.y + 60.0);
    CGFloat firstRadius = MIN( ((bounds.size.width/2.0) - 2.0),
                               ((bounds.size.height/2.0) -2.0) );
    [aGradient drawFromCenter:centerPoint radius:firstRadius
                toCenter:otherPoint radius:5.0
                options:0];
}
  Градиент рисунка 6-4 создал использование примитивного метода рисования
Gradient created using primitive drawing method

Используя кварцевые штриховки в какао

Поскольку NSGradient класс доступен только в OS X v10.5 и позже, программное обеспечение, работающее на более ранних версиях OS X, должно использовать Кварц или Базовое Изображение для рисования заливок градиента. Кварц поддерживает создание и радиальных и осевых градиентов в различных цветовых пространствах с помощью функции математического вычисления, которую Вы обеспечиваете. Использование математической функции означает градиенты создание Кварцевого масштаба использования хорошо к любому разрешению. Базовое Изображение, с другой стороны, обеспечивает фильтры для создания изображения фиксированного разрешения, состоящего из радиального, осевого, или Гауссова градиента. Поскольку конечный результат является изображением, однако, Базовые Градиенты изображения могут быть менее желательными для PDF и другого основанного на печати получения.

Для рисования Кварцевой штриховки в программе Какао Вы сделали бы следование из Вашего drawRect: метод:

  1. Получите a CGContextRef использование graphicsPort метод NSGraphicsContext. (Вы передадите эту ссылку на другие Кварцевые функции.)

  2. Создайте a CGShadingRef использование Кварца; посмотрите Градиенты в Кварце 2D Руководство по программированию.

  3. Сконфигурируйте текущую траекторию отсечения к желаемой форме для Вашей штриховки; посмотрите Установку Области Отсечения.

  4. Нарисуйте использование штриховки CGContextDrawShading.

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

Рисование на экран

Если Вы хотите принять весь экран для своего получения, можно сделать так из приложения Какао. Переход к полноэкранному режиму получения является двухступенчатым процессом:

  1. Получите желаемый экран (или экраны) для рисования.

  2. Сконфигурируйте свою среду получения.

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

Получение экрана

Какао не предоставляет прямую поддержку для получения и выпуска экранов. NSScreen класс обеспечивает доступ только для чтения к информации о доступных экранах. Чтобы получить или управлять экраном, необходимо использовать функции, найденные в Quartz Services.

Для получения всех доступных экранов можно просто вызвать CGCaptureAllDisplays функция. Для получения отдельного дисплея необходимо получить ID желаемого дисплея и вызвать CGDisplayCapture функционируйте для получения его. Следующий пример показывает, как использовать информацию, предоставленную NSScreen возразите для получения основного экрана системы.

- (BOOL) captureMainScreen
{
    // Get the ID of the main screen.
    NSScreen* mainScreen = [NSScreen mainScreen];
    NSDictionary* screenInfo = [mainScreen deviceDescription];
    NSNumber* screenID = [screenInfo objectForKey:@"NSScreenNumber"];
 
    // Capture the display.
    CGDisplayErr err = CGDisplayCapture([screenID longValue]);
    if (err != CGDisplayNoErr)
        return NO;
 
    return YES;
}

Для выпуска дисплея, Вы ранее получили, используйте CGDisplayRelease функция. При получении всех активных дисплеев можно выпустить их всех путем вызова CGReleaseAllDisplays функция.

Для получения дополнительной информации о получении и управлении экранами, посмотрите Ссылку Quartz Display Services.

Полноэкранное получение в OpenGL

Приложения, делающие полноэкранное получение, имеют тенденцию быть интенсивной графикой и таким образом использовать OpenGL для улучшения скорости рендеринга. Создание полноэкранного контекста с помощью OpenGL просто сделать от Какао. После получения желаемых дисплеев создайте и сконфигурируйте NSOpenGLContext возразите и затем вызовите setFullScreen и makeCurrentContext методы. После вызова этих методов Ваше приложение сразу переходит к полноэкранному режиму, и можно начать рисовать содержание.

При запросе полноэкранного контекста в OpenGL формат пикселя для контекста должен включать следующие атрибуты:

Перечисление 6-4 показывает основные шаги для получения всех дисплеев и установки контекст OpenGL для полноэкранного получения. Для получения информации о том, как создать NSOpenGLContext возразите, посмотрите Создание Контекста Графики OpenGL.

Перечисление 6-4  , Создающее OpenGL полноэкранный контекст

NSOpenGLContext* CreateScreenContext()
{
    CGDisplayErr err;
 
    err = CGCaptureAllDisplays();
    if (err != CGDisplayNoErr)
        return nil;
 
    // Create the context object.
    NSOpenGLContext* glContext = CreateMyGLContext();
 
    // If the context is bad, release the displays.
    if (!glContext)
    {
        CGReleaseAllDisplays();
        return nil;
    }
 
    // Go to full screen mode.
    [glContext setFullScreen];
 
    // Make this context current so that it receives OpenGL calls.
    [glContext makeCurrentContext];
 
    return glContext;
}

Как только Вы входите в полноэкранный режим со своим графическим контекстом, Ваше приложение имеет полный контроль над экраном. Для выхода из полноэкранного режима вызовите clearDrawable метод Вашего контекста OpenGL и вызова CGReleaseAllDisplays функционируйте для выпуска экранов назад к системе.

Для подробного примера кода, показывающего Вам, как ввести полноэкранный режим с помощью OpenGL и Какао, посмотрите NSOpenGL Полноэкранная выборка в Примере кода> Графика и Отображающий> OpenGL.

Полноэкранное получение в какао

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

Несмотря на то, что Вы создаете полноэкранное окно с помощью классов Какао, все еще необходимо использовать Quartz Services, чтобы получить дисплей и сконфигурировать окно должным образом. Процесс получения описан в Получении Экрана. Как только Вы получаете экран, сервер окна поднимает окно экрана, скрывающее большую часть другого содержания. Для создания полноэкранного окна видимым необходимо скорректировать его уровень для нахождения выше этого экрана. Можно получить уровень экрана с помощью CGShieldingWindowLevel функционируйте и передайте возвращенное значение setLevel: метод Вашего окна.

Перечисление 6-5 показывает метод действия, определенный в подклассе NSDocument. Объект документа использует этот метод, чтобы получить основной дисплей и создать окно для заполнения того экранного пространства. Само окно содержит единственное представление (типа MyFullScreenView) для рисования содержания. (В Вашем собственном коде Вы заменили бы это представление своим собственным представлением получения.) Ссылка на окно сохранена в myScreenWindow переменная экземпляра класса, инициализирующаяся к nil когда сначала инстанцируют класс.

Перечисление 6-5  , Создающее Какао полноэкранный контекст

- (IBAction)goFullScreen:(id)sender
{
    // Get the screen information.
    NSScreen* mainScreen = [NSScreen mainScreen];
    NSDictionary* screenInfo = [mainScreen deviceDescription];
    NSNumber* screenID = [screenInfo objectForKey:@"NSScreenNumber"];
 
    // Capture the screen.
    CGDirectDisplayID displayID = (CGDirectDisplayID)[screenID longValue];
    CGDisplayErr err = CGDisplayCapture(displayID);
    if (err == CGDisplayNoErr)
    {
        // Create the full-screen window if it doesn’t already  exist.
        if (!myScreenWindow)
        {
            // Create the full-screen window.
            NSRect winRect = [mainScreen frame];
            myScreenWindow = [[NSWindow alloc] initWithContentRect:winRect
                    styleMask:NSBorderlessWindowMask
                    backing:NSBackingStoreBuffered
                    defer:NO
                    screen:[NSScreen mainScreen]];
 
            // Establish the window attributes.
            [myScreenWindow setReleasedWhenClosed:NO];
            [myScreenWindow setDisplaysWhenScreenProfileChanges:YES];
            [myScreenWindow setDelegate:self];
 
            // Create the custom view for the window.
            MyFullScreenView* theView = [[MyFullScreenView alloc]
                                             initWithFrame:winRect];
            [myScreenWindow setContentView:theView];
            [theView setNeedsDisplay:YES];
            [theView release];
        }
 
        // Make the screen window the current document window.
        // Be sure to retain the previous window if you want to  use it again.
        NSWindowController* winController = [[self windowControllers]
                                                 objectAtIndex:0];
        [winController setWindow:myScreenWindow];
 
        // The window has to be above the level of the shield window.
        int32_t     shieldLevel = CGShieldingWindowLevel();
        [myScreenWindow setLevel:shieldLevel];
 
        // Show the window.
        [myScreenWindow makeKeyAndOrderFront:self];
    }
}

Для выхода из полноэкранного режима с помощью Какао просто выпустите полученный дисплей, измените размеры окна так, чтобы это не занимало весь экран и задерживало его уровень к NSNormalWindowLevel. Для получения дополнительной информации об окне экрана, посмотрите Ссылку Quartz Display Services.

Отключение экранных обновлений

Можно отключить и повторно включить все экранные сбросы с помощью NSDisableScreenUpdates и NSEnableScreenUpdates функции. (В OS X v10.4 и позже, можно также использовать disableScreenUpdatesUntilFlush метод NSWindow.) Можно использовать этот метод для синхронизации сбросов и с родительским и с дочерним окном. Как только Вы повторно включаете экранные обновления, все окна сбрасываются одновременно (или по крайней мере близко к нему).

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

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

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

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

Существует два шага, связанные с тем, чтобы заставлять таймер работать. Первый шаг должен создать NSTimer сам объект и указывает объект уведомить, сообщение для отправки, временной интервал для уведомления, и повторяется ли таймер. Второй шаг должен установить тот объект таймера на цикле выполнения Вашего потока. Методы scheduledTimerWithTimeInterval:invocation:repeats: и scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: выполните оба из этих шагов для Вас. Другие методы NSTimer создайте таймер, но не устанавливайте его на цикле выполнения.

Для получения информации и примеры того, как создать и использовать таймеры, посмотрите, что Таймер Программирует Темы.

Используя объекты Animation какао

NSAnimation и NSViewAnimation классы обеспечивают сложное поведение для анимаций, происходящих за конечный отрезок времени. OS X использует объекты Animation для реализации анимаций перехода для элементов пользовательского интерфейса. Можно определить объекты пользовательской анимации реализовать анимации для собственного кода. В отличие от этого NSTimer, уведомления анимации могут произойти в неправильных интервалах, позволив Вам создать анимации, которые, кажется, убыстряются или замедляются.

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

Оптимизация Вашего кода для прорисовки

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

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

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

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

Избегите вызывать синхронные обновления

При лишении законной силы частей представлений необходимо избегать использования display семья методов для принуждения незамедлительного обновления. Эти методы заставляют систему отправлять a drawRect: обменивайтесь сообщениями к затронутому представлению (и потенциально другим представлениям в иерархии) сразу, а не ожидайте до следующего цикла регулярного обновления. Если существует несколько областей для обновления, это может привести к большой дополнительной работе для кода для прорисовки.

Вместо этого необходимо использовать setNeedsDisplay: и setNeedsDisplayInRect: методы для маркировки областей как необходимость в обновлении. При вызове этих методов система собирает прямоугольники, которые Вы указываете, и объединяет их в объединенную область обновления, которую она тогда рисует во время следующего цикла обновления.

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

Снова используйте свои объекты

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

Много объектов кэшируются автоматически Какао и не должны кэшироваться в Вашем собственном коде. Например, кэши Какао NSColor объекты, представляющие обычно используемые цвета как те цвета, требуют.

Минимизируйте изменения состояния

Каждый раз, когда Вы сохраняете состояние графики, Вы подвергаетесь маленькой потере производительности. Каждый раз, когда у Вас есть объекты с теми же атрибутами рендеринга, попытайтесь привлечь их всех одновременно. Если Вы сохраняете и восстанавливаете состояние графики для каждого объекта, можно потратить впустую некоторые циклы CPU.

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