В чем разница между int и NSInteger?

Возможные дубликаты:
Когда использовать NSInteger vs int?
Почему существует NSInteger?

Можно ли использовать int и NSInteger взаимозаменяемо? Существует ли какая-либо конкретная ситуация только для использования NSInteger, вместо использования int?

Ответы

Ответ 1

Можно ли использовать int и NSInteger взаимозаменяемо?

Нет. На архитектуре LP64, используемой Apple, для современной ОС X Cocoa NSInteger имеет ширину 64 бит. Это означает, что если вы передадите NSInteger в int, сравнение с NSNotFound может завершиться неудачей. Вот пример:

NSRange theRange = [@"foo" rangeOfString @"x"];
int location = theRange.location;
if (location == NSNotFound) // comparison is broken due to truncation in line above
{
    // x not in foo
}

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

  • если вам не нужна ширина этого типа, используйте тип C, например. int или long.
  • если вы заботитесь о ширине типа, используйте типы C99 stdint.h, например. int32_t, int64_t.
  • если вам нужно, чтобы int был достаточно большим, чтобы удерживать указатель, используйте intptr_t или uintptr_t

Ответ 2

Я бы сказал, используйте стандартный C99 uintptr_t для целых чисел с указателем. Определение NSInteger выглядит достаточно облачно, чтобы не быть уверенным, что он удерживает указатель.

Используйте NSInteger, где API использует его, если нужно. Но долго будет делать для всех практических целей.

Глядя на NSObjCRunTime, я действительно не получаю мотивацию для его текущего определения. Вероятно, чтобы иметь целочисленный тип, достаточно большой, чтобы увеличить, например, максимальное количество элементов в NSArray?

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif