Swift: Как использовать препроцессоры, чтобы добавить метод расширения для * ниже * определенной версии iOS? - PullRequest
0 голосов
/ 01 октября 2018

Я пытаюсь "заполнить" метод init NSManagedObjects (context :) для ниже iOS9.Есть ли способ сделать проверку доступности препроцессора для ниже iOS10?

Имеет ли это смысл или возникнет проблема коллизии ссылок, поскольку мы не знаем, какую версию iOS будет использовать пользователь?

Обратите внимание, что это не то же самое,@available(iOS 8, *) макросы.Я хочу наоборот: если не доступно.Или, точнее, я хочу что-то вроде @available(iOS <10.0, *), "доступное, если iOS меньше 10.0"

Ответы [ 3 ]

0 голосов
/ 06 октября 2018

Попробуйте этот синтаксис, чтобы показать предупреждение:

@available(iOS, introduced: 8.0, deprecated: 10.0)

Или этот, чтобы запретить его использование в текущей цели iOS:

@available(iOS, introduced: 8.0, obsoleted: 10.0)

Вы можете даже предоставить пользовательское сообщение:

@available(iOS, introduced: 8.0, obsoleted: 10.0, message: "This is obsoleted")
0 голосов
/ 06 октября 2018

Я не думаю, что это возможно, просто полагаясь на операции во время компиляции в Swift.Если вам важно, написав расширение в Objective-C, которое определяет метод, ваша реализация переопределит платформу, когда она существует, так что это может быть жизнеспособным и простым решением.

Если вы хотите, чтобы ваша реализация тольковключите, только если нет родного, вы также можете сделать это довольно легко в Objective-C.Во-первых, у меня есть два предупреждения:

  1. Вы модифицируете CoreData, который сам по себе уже довольно динамичен, и я не уверен, как он будет реагировать.
  2. Я не могу проверитьЛюбое из того, что я говорю на этом компьютере, поэтому прокомментируйте, если оно не работает:)

В заголовке моста убедитесь, что компилятор знает, что init(context:) доступен независимо от iOSверсия:

@interface NSManagedObject ()
+(void)initialize;
-(instancetype)initWithContext:(NSManagedObjectContext* _Nonnull)ctx;
@end

+initialize методы, объявленные в категориях, выполняются независимо от того, имеет ли класс сам метод +initialize или если он есть у любой другой категории.

Тогда реализация будетвыглядят так:

@implementation NSManagedObject ()

static id initWithContext(NSManagedObject* self, SEL sel, NSManagedObjectContext* context) {
    // your implementation goes here
}

+(void)initialize {
    SEL init = @selector(initWithContext:);
    if (![self instancesRespondToSelector:init]) {
        class_addMethod(self, init, (IMP)initWithContext, "@:@");
    }
}

@end

Что, на мой взгляд, довольно просто: проверьте, поддерживает ли NSManagedObject initWithContext:, и, если нет, добавьте свою собственную реализацию.Вам не нужно предоставлять явную реализацию initWithContext:.

0 голосов
/ 04 октября 2018

Это то, что вы ищете?

@available(iOS, deprecated: 10.0)

Хотя в Swift это называется Атрибуты .Нет препроцессора.

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