swift条件函数返回

时间:2015-01-09 13:13:44

标签: ios function swift return conditional

我想知道如何在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'调用挂起。

谢谢大家。

5 个答案:

答案 0 :(得分:4)

要解释@ 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;
    }
}

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

答案 1 :(得分:3)

编译器无法知道 collectionView永远是collectionView1 或者在您的程序中collectionView2,因此它会给出错误消息。

您可以做的是添加else案例以使编译器满意。 如果一切顺利,else案例将永远不会被执行。如果有逻辑 您的程序中的错误和if条件都不匹配,然后(在 "调试和#34;配置)程序将中止并显示错误消息。

  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,这也给出了一个 运行时异常。

答案 2 :(得分:2)

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

这是 Swifter 的做法:

/// 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
    }
}

答案 3 :(得分:0)

由于你需要返回一个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
}

答案 4 :(得分:0)

我找到了解决方案!比看起来更容易。只能用“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
  }

}

现在有效。谢谢大家!