responsesToSelector на необязательные методы делегата

Я конвертирую этот проект с открытым исходным кодом Objective-C в Swift. У него есть куча необязательных делегатов.

@protocol BEMAnalogClockDelegate <NSObject>

@optional

- (void)currentTimeOnClock:(BEMAnalogClockView *)clock Hours:(NSString *)hours Minutes:(NSString *)minutes Seconds:(NSString *)seconds;
- (NSString *)dateFormatterForClock:(BEMAnalogClockView *)clock;
- (NSString *)timeForClock:(BEMAnalogClockView *)clock;
- (UIColor *)analogClock:(BEMAnalogClockView *)clock graduationColorForIndex:(NSInteger)index;
- (CGFloat)analogClock:(BEMAnalogClockView *)clock graduationAlphaForIndex:(NSInteger)index;
- (CGFloat)analogClock:(BEMAnalogClockView *)clock graduationWidthForIndex:(NSInteger)index;
- (CGFloat)analogClock:(BEMAnalogClockView *)clock graduationLengthForIndex:(NSInteger)index;
- (CGFloat)analogClock:(BEMAnalogClockView *)clock graduationOffsetForIndex:(NSInteger)index;

Я преобразовал их в Swift вот так.

@objc protocol BEMAnalogClockDelegate {
    optional func currentTimeOnClock(clock: BEMAnalogClockView, hours: String, minutes: String, seconds: String)
    optional func dateFormatterForClock(clock: BEMAnalogClockView) -> String
    optional func timeForClock(clock: BEMAnalogClockView) -> String
    optional func analogClock(clock: BEMAnalogClockView, graduationColorForIndex index: Int) -> UIColor
    optional func analogClock(clock: BEMAnalogClockView, graduationAlphaForIndex index: Int) -> CGFloat
    optional func analogClock(clock: BEMAnalogClockView, graduationWidthForIndex index: Int) -> CGFloat
    optional func analogClock(clock: BEMAnalogClockView, graduationLengthForIndex index: Int) -> CGFloat
    optional func analogClock(clock: BEMAnalogClockView, graduationOffsetForIndex index: Int) -> CGFloat
    optional func clockDidBeginLoading(clock: BEMAnalogClockView)
    optional func clockDidFinishLoading(clock: BEMAnalogClockView)
}

В проекте Objective-C перед вызовом этих необязательных методов он проверяет их доступность с помощью respondsToSelector вот так.

if ([self.delegate respondsToSelector:@selector(analogClock:graduationColorForIndex:)]) {
    self.graduationColor = [self.delegate analogClock:self graduationColorForIndex:i];
} else self.graduationColor = [UIColor whiteColor];

if ([self.delegate respondsToSelector:@selector(analogClock:graduationAlphaForIndex:)]) {
    self.graduationAlpha = [self.delegate analogClock:self graduationAlphaForIndex:i];
} else self.graduationAlpha = 1.0; 

Я напрямую преобразовал это в Swift, сделав BEMAnalogClockDelegate соответствующим NSObjectProtocol и назвав их так.

if delegate.respondsToSelector(#selector(BEMAnalogClockDelegate.analogClock(_:graduationColorForIndex:))) {
    graduationColor = delegate.analogClock!(self, graduationColorForIndex: i)
} else {
    graduationColor = UIColor.whiteColor()
}

if delegate.respondsToSelector(#selector(BEMAnalogClockDelegate.analogClock(_:graduationAlphaForIndex:))) {
    graduationAlpha = delegate.analogClock!(self, graduationAlphaForIndex: i)
} else {
    graduationAlpha = 1
}

Но это вызывает сбой EXC_BREAKPOINT при запуске проекта.

Я искал решение в Google и наткнулся на эту статью, в которой рекомендуется использовать guard let для этого .

Однако моя проблема заключается в том, как мне указать логику, которая идет в части else? Например, в первом блоке if else выше он проверяет метод в блоке if и, если он терпит неудачу, устанавливает значение для graduationColor в UIColor.whiteColor() в блоке else.

Как мне это сделать, если я использую подход guard let? Или есть лучший способ сделать это в целом?


person Isuru    schedule 07.04.2016    source источник
comment
Этот ответ может быть полезен: stackoverflow.com/a/36475215/2976878   -  person Hamish    schedule 07.04.2016


Ответы (1)


Swift также поддерживает опции для методов.

Вместо этого вы можете сделать это:

graduationColor = delegate.analogClock?(self, graduationColorForIndex: i) ?? UIColor.whiteColor()

Или длинный путь:

if let graduationColor = delegate.analogClock?(self, graduationColorForIndex: i) {
   self.graduationColor = graduationColor
} else  {
   self.graduationColor = UIColor.whiteColor()
}
person Angel G. Olloqui    schedule 07.04.2016