64-разрядные изменения в какао API

64-разрядные изменения в Какао API в основном предназначены для тех параметр и типы возврата, требуемые для 64-разрядного обращения. Однако непротиворечивость, простота портирования и «подобранность импедансов» являются также целями, и таким образом большинство 32-разрядных количеств в API растет до 64 битов. Какао 64-разрядные изменения попадает в три главных категории: целые числа, значения с плавающей точкой и константы перечисления.

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

Целые числа

Самое большое 64-разрядное изменение в Какао API является введением NSInteger и NSUInteger типы данных. Эти два типа теперь заменяют большинство случаев int и unsigned int в заголовках платформы. Параметр и типы возврата, остающиеся как int и unsigned int в Какао заголовочные файлы неизменны по одной из двух причин:

На 64-разрядной архитектуре, NSInteger и NSUInteger определяются как long и unsigned long, соответственно. Для поддержания совместимости на уровне двоичных кодов с 32-разрядными приложениями они объявляются в заголовочном файле Основы NSObjCRuntime.h использование __LP64__ макрос для различения 32-разрядные и 64-разрядные сборки, следующим образом:

#if __LP64__
    typedef long NSInteger;
    typedef unsigned long NSUInteger;
#else
    typedef int NSInteger;
    typedef unsigned int NSUInteger;
#endif

Дополнительно для 64-разрядной инициативы, много новых методов были добавлены к платформам Какао с «целым числом» на их имена. Эти методы являются дубликатами к другим методам в том же классе с «интервалом» на их имена; эти методы должны продолжать иметь дело со значениями, которые являются в частности int. «Целочисленные» методы имеют параметр или типы возврата NSInteger или NSUInteger в то время как «международные» методы принимают или возвращаемые значения собственных типов int или unsigned int. Таблица 2-1 перечисляет новые методы.

Табличные 2-1  «Целочисленные» методы добавили к платформам Какао

Класс

Методы

NSCoder

encodeInteger:forKey:

decodeIntegerForKey:

NSUserDefaults

setInteger:forKey:

integerForKey:

(Примечание: доступный начиная с OS X v10.0)

NSString

integerValue

NSCell

integerValue

setIntegerValue:

NSControl

integerValue

setIntegerValue:

NSScanner

scanInteger:

NSNumber

integerValue

unsignedIntegerValue

initWithInteger:

initWithUnsignedInteger:

numberWithInteger:

numberWithUnsignedInteger:

NSActionCell

integerValue

Устанавливать пределы для нового NSInteger и NSUInteger типы, NSObjCRuntime.h также определяет следующие константы:

#define NSIntegerMax LONG_MAX
#define NSIntegerMin LONG_MIN
#define NSUIntegerMax ULONG_MAX

Создание 32-разрядного как 64-разрядный

Как показано в предыдущем разделе, Какао определяет NSInteger и NSUInteger условно (использующий __LP64__ макрос) так, чтобы, пока проект последовательно использовал новые типы данных, базовый тип примитива, варьируется согласно тому, является ли целевая архитектура 32-разрядной или 64-разрядной.

NS_BUILD_32_LIKE_64 макрос препроцессора работает другим способом. Это объявляет NSInteger быть long (вместо int) и NSUInteger быть long unsigned int даже на 32-разрядных частях исходной основы.

#if __LP64__ || NS_BUILD_32_LIKE_64
    typedef long NSInteger;
    typedef unsigned long NSUInteger;
#else
    typedef int NSInteger;
    typedef unsigned int NSUInteger;
#endif

Это позволяет сделать что-то как следующее, не получая предупреждения.

NSInteger i;
printf("%ld", i);

NS_BUILD_32_LIKE_64 когда совместимость на уровне двоичных кодов не является беспокойством, такой, создавая приложение, макрос полезен.

Значения с плавающей точкой

Количества с плавающей точкой в Базовой Графической платформе (Кварц), которые являются float на 32-разрядной архитектуре, расширяются до double обеспечить более широкий диапазон и точность для графических количеств. Базовая Графика объявляет новый тип для количеств с плавающей точкой, CGFloat, и объявляет его условно и для 32-разрядного и для 64-разрядного. Это изменение влияет на Какао из-за своей близкой зависимости от Базовой Графики. Где значение параметра или возвращаемое значение в платформах Какао являются графическим количеством, CGFloat теперь замены float.

CGFloat изменения сделали в Основе и, особенно, Набор Приложения являются столь многочисленными, что его более простое для указания на методы с параметрами с плавающей точкой и типами возврата, не изменяющимися на CGFloat; т.е. они остаются как float. Эти методы попадают в определенные категории, описанные в заголовках к Таблице 2-2, Таблице 2-3, Таблице 2-4, Таблице 2-5 и Таблице 2-6.

Таблица 2-2  Специфичные для типа параметры и возвращаемые значения

Класс

Методы

NSActionCell

floatValue

NSCell

floatValue

setFloatValue:

NSControl

floatValue

setFloatValue:

NSString

floatValue

NSNumber

floatValue

initWithFloat:

numberWithFloat:

NSScroller

setFloatValue:knobProportion:

NSPrinter

floatForKey:inTable::

NSUserDefaults

floatForKey:

setFloat:forKey:

NSScanner

scanFloat:

NSKeyedArchiver

encodeFloat:forKey:

NSKeyedUnarchiver

decodeFloatForKey:

NSCoder

encodeFloat:forKey:

decodeFloatForKey:

NSByteOrder.h

Приблизительно дюжина функций «подкачки».

Таблица 2-3  Наборные факторы

Класс

Методы

NSATSTypesetter

hyphenationFactor

hyphenationFactorForGlyphAtIndex:

setHyphenationFactor:

NSLayoutManager

hyphenationFactor

hyphenationFactor

NSTypesetter

hyphenationFactor

setHyphenationFactor:

NSParagraphStyle

hyphenationFactor

tighteningFactorForTruncation

Табличные 2-4  Носители: частота кадров, объем, процент анимации

Класс

Методы

NSAnimation

frameRate

setFrameRate:

currentValue

animation:valueForProgress:

NSMovieView

setRate:

rate

setVolume:

volume

NSSound

setVolume:

volume

Табличный 2-5  фактор Сжатия

Класс

Методы

NSBitmapImageRep

getCompression:factor:

setCompression:factor:

TIFFRepresentationUsingCompression:factor:

TIFFRepresentationOfImageRepsInArray:usingCompression:factor:

NSImage

TIFFRepresentationUsingCompression:factor:

Табличное 2-6  давление События планшета и вращение

Класс

Методы

NSEvent

pressure

rotation

tangentialPressure

mouseEventWithType:location:modifierFlags:timestamp:windowNumber:context:eventNumber:clickCount:pressure:

Константы перечисления

Проблема с перечислением (enum) константы - то, что их типы данных часто неопределенны. Другими словами, enum константы не очевидно unsigned int. С традиционно созданными перечислениями компилятор фактически устанавливает базовый тип на основе того, что это находит. Базовый тип может быть (подписан) int или даже long. Возьмите следующий пример:

type enum {
    MyFlagError = -1,
    MyFlagLow = 0,
    MyFlagMiddle = 1,
    MyFlagHigh = 2
} MyFlagType;

Компилятор смотрит на это объявление и, считая отрицательную величину присвоенной одной из задействованных констант, объявляет базовый тип перечисления int. Если диапазон значений для элементов не вписывается int или unsigned int, тогда базовый тип тихо становится 64-разрядным (long). Базовый тип количеств, определенных как перечисления, может таким образом изменить тихо размер для согласований со значениями в перечислении. Это может произойти, компилируете ли Вы 32-разрядный или 64-разрядный. Само собой разумеется, эта ситуация представляет препятствия для совместимости на уровне двоичных кодов.

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

typedef enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
} NSCellType;

существует теперь это:

enum {
    NSNullCellType = 0,
    NSTextCellType = 1,
    NSImageCellType = 2
};
typedef NSUInteger NSCellType;

Тип перечисления определяется с точки зрения NSInteger или NSUInteger заставить основное перечисление ввести 64-разрядный способный на 64-разрядной архитектуре. Для OS X v10.5 все перечисления, объявленные в платформах Какао теперь, принимают эту форму. В некоторых случаях тип перечисления теперь объявляется, где каждый не существовал прежде.

К сожалению, это изменение влияет на проверку типа констант перечисления; можно передать любое целочисленное значение в параметре метода, введенном как, скажем, NSCellType, не только одно из значений в перечислении. Однако изменение действительно позволяет более определенный ввод битовых масок, ранее объявленных как unsigned int. Можно теперь использовать typedefs для параметров, которые являются битовыми масками. Например,

- (NSComparisonResult)compare:(NSString *)string options:(unsigned)mask;

может теперь быть

- (NSComparisonResult)compare:(NSString *)string options:(NSStringCompareOptions)mask;

Другие связанные изменения (и неизменения)

Использование некоторых из других примитивных типов C в Какао, которое API изменяет в 64-разрядной инициативе, в то время как другие незатронуты. Следующее суммирует изменения и неизменения:

Какао OpenGL API (включая классы NSOpenGLContext, NSOpenGLPixelBuffer, NSOpenGLPixelFormat, и NSOpenGLView) следуйте за изменениями типа данных, внесенными для платформы OpenGL C для Leopard путем принятия стандартных типов OpenGL такой как GLint, GLsizei, и GLenum для параметров и возвращаемых значений. Эти типы были выбраны частично для поддержания совместимости на уровне двоичных кодов под 32-разрядным (где long и int тот же размер).

Время выполнения Objective C API (/usr/include/objc) подвергся значительной модификации для OS X v10.5. Большинство разработчиков Какао непосредственно не вызывает эти функции, таким образом, эти изменения не должны влиять на них. Однако при использовании времени выполнения Objective C API необходимо знать, что существуют импликации для 64-разрядных двоичных файлов. Если Вы разрабатываете свой 64-разрядный проект, Вы не можете использовать старое время выполнения Objective C API.