可选委托方法上的responssToSelector



我正在将这个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崩溃。

我在谷歌上搜索了一个解决方案,并看到了这篇文章,它建议为此使用guard let

然而,我的问题是如何指定else部分中的逻辑?例如,在上面的第一个if else块中,它检查if块中的方法,如果失败,它在else块中将graduationColor的值设置为UIColor.whiteColor()

如果我使用guard let方法,我该如何做到这一点?或者有更好的方法来做到这一点吗?

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()
}

相关内容

  • 没有找到相关文章

最新更新