在可选的委托方法上的respondsToSelector

时间:2016-04-07 14:12:38

标签: ios objective-c swift respond-to swift2.2

我正在将this 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; 

我通过使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 } ,将其直接转换为Swift。

guard let

但是这会在项目运行时导致EXC_BREAKPOINT崩溃。

我搜索了一个解决方案并遇到了this文章,建议使用else

但是我的问题是如何指定if else部分的逻辑?例如,在上面的第一个if块中,它会检查graduationColor块中的方法,如果失败,则会将UIColor.whiteColor()的值设置为else guard let 1}}阻止。

如果我使用JSONObject方法,该怎么办?或者有更好的方法来做到这一点吗?

1 个答案:

答案 0 :(得分:2)

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