【问题标题】:Skip/ignore method in iOSiOS中的跳过/忽略方法
【发布时间】:2015-03-12 17:54:53
【问题描述】:

如何在 iOS 中跳过完整的方法?我知道如何测试 iOS 版本 inside 一个方法,但不知道如何完全忽略一个方法。

具体示例:iOS8 增加了自定尺寸表格视图单元格,不再需要heightForRowAtIndexPath:estimatedHeightForRowAtIndexPath: 方法。但我确实需要它们用于 iOS7。现在,当我单步执行 iOS8 中的代码时,这两个方法都会被调用,即使它们不再需要。

【问题讨论】:

  • 您可以使用条件。 (#if - #else - #endif)。这样就可以在编译时决定是否执行某些代码行。
  • 当然可以,但是我要测试什么?
  • @Koen 这可能会有所帮助stackoverflow.com/questions/24268070/…
  • 好吧,你可以有两个不同的委托类实现,然后选择你创建的那个。
  • 听起来最好的选择是将运行时检查作为方法的第一行,并在不需要时跳过整个正文。

标签: ios objective-c uitableview


【解决方案1】:

您将UITableViewDelegate 设置为UITableView 的委托,并且您希望向不同版本的iOS 呈现不同的委托方法。

UITableView 将在调用[delegate tableView:self heightForRowAtIndexPath:indexPath] 之前调用[delegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)]

这需要自定义-respondsToSelector:。在您的 UITableViewDelegate 类中添加此方法。

- (BOOL)respondsToSelector:(SEL)aSelector
{
    // If this device is running iOS 8 or greater.
    if ([[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] != NSOrderedAscending) {
        if (aSelector == @selector(tableView:heightForRowAtIndexPath:))
            return NO;

        if (aSelector == @selector(tableView:estimatedHeightForRowAtIndexPath:))
            return NO;
    }

    return [super respondsToSelector:aSelector];
}

更新:我修复了委托方法名称。呃!

【讨论】:

  • @vikingosegundo 是的,我的意思是-tableView:heightForRowAtIndexPath:-tableView:estimatedHeightForRowAtIndexPath:。对此感到抱歉。
  • 这是一个聪明的解决方案!不是 100% 确定它会起作用(有点“双倍劳累和麻烦”),但它当然值得考虑。
【解决方案2】:

根据 iOS 版本提供不同的委托。这允许您将代码封装在有意义命名的块中(您的界面将表明它是 iOS7),并且您不会对 respondsToSelector 做任何可能破坏您的类的子类的诡计确实 想使用这些方法。

@interface MyTableViewDelegate : NSObject <UITableViewDelegate>
@end

@interface MyTableViewDelegateiOS7 : MyTableViewDelegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
@end

@implementation YourClass : .. <..>
// ..
- (void)loadView {
  [super loadView];
  if ([[[UIDevice currentDevice] systemVersion] compare:@"8.0" options:NSNumericSearch] != NSOrderedAscending) {
    self.tableView.delegate = [[MyTableViewDelegate alloc] init];
  } else {
    self.tableView.delegate = [[MyTableViewDelegateiOS7 alloc] init];
  }
}
@end

【讨论】:

  • MyTableViewControllerUITableView 的代表(和数据源)。如果我理解正确,您的回答表明另一个班级充当代表?
  • 没错。事实上,另外两个类,虽然 iOS7 一个从另一个扩展而来,所以您不会重复代码,只需在需要的地方添加 iOS7 功能。
  • 好的,我明白了。我想我之前已经阅读过关于使用单独的委托/数据源类的信息,但从未看到需要它。可能就是这种情况。
  • @Koen,确实最好有一个自己的数据源/委托类,因为这提高了可重用性并根据单一责任原则授权编码。也可以看看去年的 WWDC 视频 «Advances in UICollectionViews» 或类似的。很明显,苹果也使用了这种方法。
猜你喜欢
  • 2015-02-02
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 2017-01-26
  • 1970-01-01
  • 2012-08-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多