Подтвердить что ты не робот

Почему нет атрибута "nonnil" для clang?

nonnull работает для C-функций, но не obj-c-методов. Чтобы быть ясным, я предлагаю это

- (void)doSomethingWithRequiredString:(NSString * __attribute((nonnil)))requiredString
                                  bar:(NSString *)optionalString);

или (больше как nonnull)

- (void)doSomethingWithRequiredString:(NSString *)requiredString
                                  bar:(NSString *)optionalString)
__attribute((nonnil(0)));

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

4b9b3361

Ответ 1

Вы полностью можете. Единственное, что вы делаете неправильно, это думать, что параметры метода индексируются 0, когда на самом деле они являются 1-индексированными (oh и it nonnull, not nonnil):

- (void)doSomethingWithRequiredString:(NSString *)requiredString
                                  bar:(NSString *)optionalString
        __attribute((nonnull(1)));

Теперь, когда вы пытаетесь использовать это:

id thing = ...;
[thing doSomethingWithRequiredString:nil bar:@"42"];

Xcode предупредит вас, говоря: "Нуль передан вызываемому абоненту, который требует непустого аргумента".

Кроме того, если вы не учитываете "(1)" часть атрибута __, он предполагает, что требование не-nil применяется ко всем параметрам.

Clang распознает атрибуты GCC, а определение GCC атрибута nonnull находится здесь: http://gcc.gnu.org/onlinedocs/gcc-4.0.0/gcc/Function-Attributes.html#index-g_t_0040code_007bnonnull_007d-function-attribute-1733


Обновление: с Xcode 6.3 поддерживается более чистый синтаксис.

В свойствах и методах ключевые слова: nullable, nonnull и null_unspecified.

Итак, ваша подпись метода станет таковой:

- (void)doSomethingWithRequiredString:(nonnull NSString *)requiredString
                                  bar:(nullable NSString *)optionalString;

Ответ 2

В Xcode 6.3 бета новые функции Objective-C были добавлены для выражения (не) обнуления в заголовках: https://developer.apple.com/swift/blog/?id=22

Ответ 3

Да, есть.

Вы можете сделать следующее:

- (nullable AAPLListItem *)itemWithName:(nonnull NSString *)name;
- (NSInteger)indexOfItem:(nonnull AAPLListItem *)item;

https://developer.apple.com/swift/blog/?id=25