可选委托方法上的 respondsToSelector
respondsToSelector on optional delegate methods
我正在将 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
并像这样调用它们,直接将其转换为 Swift。
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 崩溃。
我在谷歌上搜索了一个解决方案,发现了 this 文章,其中建议为此使用 guard let
。
但是我的问题是如何指定 else
部分中的逻辑?例如,在上面的第一个 if else
块中,它检查 if
块中的方法,如果失败,它将 graduationColor
的值设置为 UIColor.whiteColor()
在 else
块。
如果我使用 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()
}
我正在将 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
并像这样调用它们,直接将其转换为 Swift。
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 崩溃。
我在谷歌上搜索了一个解决方案,发现了 this 文章,其中建议为此使用 guard let
。
但是我的问题是如何指定 else
部分中的逻辑?例如,在上面的第一个 if else
块中,它检查 if
块中的方法,如果失败,它将 graduationColor
的值设置为 UIColor.whiteColor()
在 else
块。
如果我使用 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()
}