繁体   English   中英

swift条件函数返回

[英]swift conditional function return

我想知道如何在swift中管理条件返回。 例如,我正在返回一个自定义的UICollectionViewCell,具体取决于调用哪个collectionview委托:

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
      if (collectionView.isEqual(collectionView1)) {
         var cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell1", forIndexPath: indexPath) as Cell1
         return cell
      }
      else if (collectionView.isEqual(collectionView2)) {
        var cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell2", forIndexPath: indexPath) as Cell2
        return cell
      }
}

编译器说“在函数中丢失返回语句以返回UICollectionViewCell”,即使在两种情况下我都返回一个单元格。

我解决了这个问题

return UICollectionViewCell()

在函数的底部,但我认为这不是正确的方法。

我知道我可以在第一个'if'之上声明单元格,修改它并在'if'之外的函数末尾返回它,然后'dequeueReusableCellWithIdentifier'调用挂起。

谢谢你们。

要解释@ MidhunMP的答案,现在您的代码能够以没有任何返回值的方式结束。 例如,查看此代码,与您的代码类似:

func myFunc() -> Int {
    let myNumber = random() % 3
    if myNumber == 0 {
        return 0
    }
    else if myNumber == 1 {
        return 1
    }
}

如果myNumber是2怎么办? 函数结束时没有任何返回值,这不可能发生。

将return语句移动到代码的末尾,或者添加else子句。 两者都确保您的函数在所有情况下都会返回值。

您将需要:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    var cell = UICollectionViewCell()
    if (collectionView.isEqual(collectionView1)){
        cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell1", forIndexPath: indexPath) as Cell1
    } else if (collectionView.isEqual(collectionView2)){
        cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell2", forIndexPath: indexPath) as Cell2
    }
    return cell
}

要么,

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    var cell = UICollectionViewCell()
    if (collectionView.isEqual(collectionView1)){
        cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell1", forIndexPath: indexPath) as Cell1
    return cell
    } else if (collectionView.isEqual(collectionView2)){
        cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell2", forIndexPath: indexPath) as Cell2
    return cell
    } else {
        return cell;
    }
}

但是,使用第一个,因为它更优雅,更容易理解其含义。

编译器无法知道 collectionView将始终是程序中的collectionView1collectionView2 ,因此它会给出错误消息。

您可以做的是添加一个else案例以使编译器满意。 如果一切顺利,则永远不会执行else案例。 如果在你的程序中的逻辑错误和双方if条件不匹配,那么(在“调试”配置)程序将一个错误信息中止。

  if (collectionView.isEqual(collectionView1)) {
       let cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell1", forIndexPath: indexPath) as Cell1
       // set cell properties ... 
       return cell
  }
  else if (collectionView.isEqual(collectionView2)) {
      let cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell2", forIndexPath: indexPath) as Cell2
      // set cell properties ... 
      return cell
  }
  else {
      assertionFailure("unexpected collectionView")
      return UICollectionViewCell()
  }

或者(这只是前两个答案的略微变体),将cell声明为if块之外的隐式解包的可选项:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    var cell : UICollectionViewCell!
    if (collectionView.isEqual(collectionView1)){
        cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell1", forIndexPath: indexPath) as Cell1
        // set cell properties ... 
    } else if (collectionView.isEqual(collectionView2)){
        cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell2", forIndexPath: indexPath) as Cell2
        // set cell properties ... 
    }
    return cell
}

如果没有条件匹配,则返回nil ,这也会产生运行时异常。

首先,请大家回答,请不要使用var 其次,当然这是一个正确的编译器错误,因为委托方法不能确保collectionView是你定义的那个之一,并且要求你返回一个有效的单元格,所以如果你想在代码中保留两个明确的情况那么你需要定义一个有效但从未使用过的案例。 还要注意,将您的单元格转换为正确的子类在这里是没用的,因为它们仍然被实例化为正确的类,并且仍然作为委托方法签名建议的UICollectionViewCell返回。

这是一种更快捷的方式:

/// define this in any .swift file included in your project
func ~=<T: AnyObject>(lhs: T, rhs: T) -> Bool {
    return lhs === rhs
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let reuseIdentifier = cellReuseIdentifierForCollectionView(collectionView)
    return epgCollectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath)
}

private func cellReuseIdentifierForCollectionView(collectionView: UICollectionView) -> String {
    switch collectionView {
    case collectionView1:
        return "Cell1"
    case collectionView2:
        return "Cell2"
    default:
        return "" // this never happens but is still a bit of a code smell
    }
}

因为你需要返回一个UICollectionViewCell ,如果为它创建一个var并返回它会更好(我不是在方法中编写多个return语句的粉丝)所以你可以将它改为:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
      var cell = UICollectionViewCell()
      if (collectionView.isEqual(collectionView1))
      {
         cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell1", forIndexPath: indexPath) as Cell1
      }
      else if (collectionView.isEqual(collectionView2))
      {
         cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell2", forIndexPath: indexPath) as Cell2
      }
      return cell
}

我找到了解决方案! 比看起来更容易。 只能用“else”替换“else if”:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
  if (collectionView.isEqual(collectionView1)) {
     var cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell1", forIndexPath: indexPath) as Cell1
     return cell
  }
  else (collectionView.isEqual(collectionView2)) {
    var cell = self.epgCollectionView.dequeueReusableCellWithReuseIdentifier("Cell2", forIndexPath: indexPath) as Cell2
    return cell
  }

}

它现在有效。 谢谢大家!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM