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

У указателя отсутствует спецификатор типа nullability

В Xcode 7 GM я начал получать это предупреждение:

У указателя отсутствует спецификатор типа nullability (_Nonnull, _Nullable или _Null_unspecified)

В следующем объявлении функции (расширение NSUserDefaults)

- (void)setObject:(nullable id)value
           forKey:(NSString *)defaultName
    objectChanged:(void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(void(^)(NSUserDefaults *userDefaults, id value))remainHandler;

Почему это предупреждение отображается и как его исправить?

4b9b3361

Ответ 1

Вы должны указать nullable также для обработчиков/блоков

- (void)setObject:(nullable id)value
           forKey:(nonnull NSString *)defaultName
    objectChanged:(nullable void(^)(NSUserDefaults *userDefaults, id value))changeHandler
    objectRamains:(nullable void(^)(NSUserDefaults *userDefaults, id value))remainHandler;

Зачем? Это из-за Свифта. Swift допускает необязательные параметры (?), Чего нет у Objective-C. Это делается как мост между ними обоими, чтобы компилятор Swift знал, что эти параметры являются необязательными. "Nonnull" сообщит компилятору Swift, что аргумент является обязательным. Обнуляемый, что это необязательно

Для получения дополнительной информации читайте: https://developer.apple.com/swift/blog/?id=25

Ответ 2

Вы можете использовать следующие макросы вокруг блоков деклараций (функций и переменных) в объектных заголовках c:

NS_ASSUME_NONNULL_BEGIN 

NS_ASSUME_NONNULL_END

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

Как в:

@interface SMLBaseUserDetailsVC : UIViewController < UICollectionViewDelegate>
NS_ASSUME_NONNULL_BEGIN

@property (nonatomic, readonly) IBOutlet UIScrollView *detailsScrollView;
@property (nonatomic, readonly) IBOutlet UICollectionView *photoCV;
@property (nonatomic, weak, readonly) SMLUser *user;
- (IBAction)flagUser:(id)sender;
- (IBAction)closeAction:(nullable id)sender;
- (void) prefetchPhotos;

NS_ASSUME_NONNULL_END

@end

Изменить * Почему??? потому что для класса objective-c, который должен быть совместим с быстрым, вам нужно объявить значение nullability, чтобы компилятор знал, что свойства обрабатываются как быстрые или нет. Неверные объектные свойства c известны как опции в swift, и использование этих макросов в сочетании с объявляемыми с нулевым объявлением объявлениями свойств позволяет компилятору относиться к ним как к опциям (опции - monads - объект, который обертывает либо объект, либо nil).

Ответ 3

Правильное объявление рабочего метода, принятое компилятором:

- (void)setObject:(nullable id)value
           forKey:(nonnull NSString *)defaultName
    objectChanged:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))changeHandler
    objectRamains:(nullable void(^)(NSUserDefaults *_Nonnull userDefaults, id _Nullable value))remainHandler;

Ответ 4

Я отправляю этот ответ, чтобы сказать, зачем добавлять _Nonnull или nullable.

Согласно этому блогу: https://developer.apple.com/swift/blog/?id=25

Одна из замечательных особенностей Swift заключается в том, что он прозрачно взаимодействует с кодом Objective-C, как существующими фреймворками, написанными в Objective-C, так и кодом в вашем приложении. Однако в Swift существует сильное различие между необязательными и необязательными ссылками, например. NSView vs. NSView?, а Objective-C представляет обе эти два типа как NSView *. Поскольку компилятор Swift не может определить, является ли конкретный NSView * необязательным или нет, тип вводится в Swift как неявно развернутый необязательный, NSView!.

все это для Swift.

Ответ 5

Чтобы отключить это предупреждение для всего вашего проекта

  1. Перейти в настройки сборки

  2. Убедитесь, что вы просматриваете вкладку "Все", а не "Основные" или "Индивидуальные"

  3. Поиск поля Other Warning Flags

  4. Добавьте следующий флаг: -Wno-nullability-completeness.

  5. Теперь очистите и соберите (cmd + shift + k, затем cmd + r)

  6. Выйдите из xCode и снова откройте (Не пропустите этот шаг!)

    --note, может пройти несколько секунд, чтобы предупреждения исчезли, даже после того, как вы закончите сборку и перезапуск xCode, для меня это займет около 15 секунд для полного обновления xCode

Ответ 6

Удалите приведенный ниже макрос из вашего файла .h, и предупреждение исчезнет

NS_ASSUME_NONNULL_BEGIN 

NS_ASSUME_NONNULL_END