Как комментировать API Objective-C для использования в Swift (например, типы возврата)

17

Согласно примечаниям к выпуску Xcode, Apple «проверила» свои существующие API-интерфейсы для удаления неявно развернутых опций. Это означает, что вместо T! их API будут возвращать T или T? , если это необходимо.

Где они это делают? Как я могу аннотировать / обернуть мой существующий код Objective-C (особенно библиотеки), чтобы сделать его более чистым для использования с Swift?

    
задан nschum 09.09.2014 в 16:35
источник
  • Сравните devforums.apple.com/message/1020251 (требуется вход для разработчиков). –  Martin R 09.09.2014 в 16:46

2 ответа

16

Xcode 6.3 / Swift 1.2

Xcode 6.3 добавлена ​​официальная поддержка аннотации обнуляемости в Objective-C.

допустимость пустых

Недействительность значения может быть объявлена ​​путем аннотации типа с ключевыми словами __nullable , __nonnull и __null_unspecified (по умолчанию). В свойствах и методах ключевые слова: nullable , nonnull и null_unspecified .

Примеры из примечаний к выпуску Xcode

   - (void)registerNib:(nonnull UINib *)nib
forCellReuseIdentifier:(nonnull NSString *)identifier;

- (nullable UITableViewCell *)cellForRowAtIndexPath:(nonnull NSIndexPath)indexPath;

@property (nonatomic, readwrite, retain, nullable) UIView *backgroundView;

Изменение значения по умолчанию

null_unspecified (что соответствует T! ) является значением по умолчанию для всего существующего кода. Полезной функцией является возможность изменения по умолчанию для разделов вашего API.

NS_ASSUME_NONNULL_BEGIN
// nonnull is the default here
NS_ASSUME_NONNULL_END

Это удаляет много шума, поскольку методы, которые принимают и обрабатывают nil, обычно являются исключением, а не правилом. Лично я бы использовал это для всех проверенных API.

null_resettable

null_resettable - дополнительная аннотация, которая используется для необычного случая, когда вы можете установить свойство в nil, но никогда не будет быть nil (потому что он сбрасывает к значению по умолчанию).

 @property (nonatomic, retain, null_resettable) UIColor *tintColor;

Лично я бы избегал этого поведения для нового кода. Гибридный характер таких свойств не подходит для Swift.

Xcode 7 / Swift 2 (бета)

Xcode 7 добавляет поддержку аннотирования типичных типов в Objective-C.

Аннотации общего типа для коллекций

NSArray , NSSet и NSDictionary (которые автоматически соединяются с Swift Array , Set и Dictionary могут быть аннотированы с типом их содержимого.

@property NSArray<NSString *> *stringArray;
@property NSSet<NSString *> *stringSet;
@property NSDictionary<NSString *, NSString *> *stringDict;

Также существует ключевое слово __kindof , которое сообщает компилятору Objective-C быть менее строгим и допускает downcasting. Но это не влияет на сторону Swift.

Аннотации общего типа для пользовательских классов

@interface MyArray1<__covariant T> : NSObject
- (void)addObject:(T)object;
@end

@interface MyArray2<__covariant T : NSObject *> : NSObject
- (void)addObject:(T)object;
@end

@interface MyArray3<__covariant T : id<NSCopying>> : NSObject
- (void)addObject:(T)object;
@end

@implementation не знает о T и использует id / NSObject * / id<NSCopying> , как всегда.

    
ответ дан nschum 09.02.2015 в 23:49
источник
  • вы забыли __ в фрагментах кода? –  progrmr 06.04.2015 в 23:55
  • Нет, как я уже сказал, подчеркивания не используются в свойствах и методах. Он работает так же, как __weak и слабый (см. Stackoverflow.com/questions/23944361/ios-weak-vs-weak). –  nschum 07.04.2015 в 11:16
11

Я считаю, что есть способ сделать это в данный момент. Похоже, что информация компилируется в

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator

в таких файлах, как

UIKit.apinotesc 
UIKit.swiftdoc 
UIKit.swiftmodule

Классы *.swiftmodule генерируются Xcode как часть быстрой сборки, но дополнительная информация может быть в файле .apinotesc , который, как представляется, не является документированной формой его создания в данный момент.

Однако команда swift имеет параметр -apinotes , который используется для его создания. Вы можете увидеть из /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/UIKit.apinotesc , что вы можете проанализировать это с помощью:

xcrun swift -apinotes -binary-to-yaml  -o=- /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphonesimulator/UIKit.apinotesc

Это создает файл YAML, похожий на:

Classes:         
  - Name:            NSFileProviderExtension
    Availability:    available
    AvailabilityMsg: ''
    Methods:         
      - Selector:        'URLForItemWithPersistentIdentifier:'
        MethodKind:      Instance
        Nullability:     [ N ]
        NullabilityOfRet: U
        Availability:    available
        AvailabilityMsg: ''

Если бы я был игроком ставок (а я нет), я бы сказал, что MethodKind определяет, является ли это Instance или Class и что Nullability используется Swift для определения того, является ли это необязательно или нет. Я бы заподозрил:

  • U - (неявно) разворачивается необязательно
  • O - необязательный
  • N - необязательно?

Это дикие догадки.

    
ответ дан AlBlue 17.09.2014 в 13:03
источник
  • FYI это частная функциональность, подлежащая изменению в будущих выпусках без предупреждения. Мы не собираемся раскрывать эту функциональность третьим сторонам, таким как вы. –  Jack Lawrence 10.10.2014 в 23:22
  • С удовольствием полагаю, что это было полезное упражнение в понимании того, откуда Свифт получал эту информацию: :) –  AlBlue 11.10.2014 в 23:41