避免使用强制类型转换

3

我在我的代码中遇到了"Force cast violation : Force casts should be avoided warning"警告:

daysCombinedFinal = daysCombined[0] as! [Any?]

以下是翻译的结果:

以下是截图:

图片中显示的警告

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if  let cell = tableView.dequeueReusableCell(withIdentifier: "location", for: indexPath) as? TravelShopCustomCell {
        if !isFirstTime && self.nameArray.count != 0 {
            var daysCombined = [Any]()
            var daysCombinedFinal = [Any?]()
            daysCombined = [self.combinedArray[0]]
            daysCombinedFinal = daysCombined[0] as? [Any?] ?? []
            let str = daysCombinedFinal.flatMap { $0 as? String }.joined(separator:" ")
            var startAMCombined = [Any]()
            var startAMCombinedFinal = [Any?]()
            startAMCombined = [self.combinedStartAMArray[0]]
            startAMCombinedFinal = startAMCombined[0] as? [Any?] ?? []
            var endPMCombined = [Any]()
            var endPMCombinedFinal = [Any?]()
            endPMCombined = [self.combinedEndPMArray[0]]
            endPMCombinedFinal = endPMCombined[0] as? [Any?] ?? []
            cell.operatingDaysLabel.text = str
            let isAMEqual = checkArrayStatus(testArray: [startAMCombinedFinal as Any])
            let isPMEqual = checkArrayStatus(testArray: [endPMCombinedFinal as Any])
            if isAMEqual && isPMEqual {
                self.mergedArray = arrayMerger(array1: startAMCombinedFinal, array2: endPMCombinedFinal)
            }
            let startTimeString = self.mergedArray[0] as? String
            let endTimeString = self.mergedArray[1] as? String
            cell.operatingTimeLabel.text = startTimeString! + " - " + endTimeString!
            return cell
        } else if isFirstTime && self.nameArray.count != 0 {
            var daysCombined = [Any]()
            var daysCombinedFinal = [Any?]()
            daysCombined = [self.combinedArray[indexPath.row]]
            daysCombinedFinal = daysCombined[0] as! [Any?]
            let str = daysCombinedFinal.flatMap { $0 as? String }.joined(separator:" ")
            var startAMCombined = [Any]()
            var startAMCombinedFinal = [Any?]()
            startAMCombined = [self.combinedStartAMArray[indexPath.row]]
            startAMCombinedFinal = startAMCombined[0] as! [Any?]
            var endPMCombined = [Any]()
            var endPMCombinedFinal = [Any?]()
            endPMCombined = [self.combinedEndPMArray[indexPath.row]]
            endPMCombinedFinal = endPMCombined[0] as! [Any?]
            cell.operatingDaysLabel.text = str
            let isAMEqual = checkArrayStatus(testArray: [startAMCombinedFinal as Any])
            let isPMEqual = checkArrayStatus(testArray: [endPMCombinedFinal as Any])
            if isAMEqual && isPMEqual {
                self.mergedArray = arrayMerger(array1: startAMCombinedFinal, array2: endPMCombinedFinal)
            }
            let startTimeString = self.mergedArray[0] as? String
            let endTimeString = self.mergedArray[1] as? String
            cell.operatingTimeLabel.text = startTimeString! + " - " + endTimeString!
            return cell
        }
        return cell
    } else {
        fatalError("Dequeueing SomeCell failed")
    }
}

数组声明如下:
var dateArray = [Any]()
var endAmTimeArray = [Any]()
var endPmTimeArray = [Any]()
var startAmTimeArray = [Any]()
var startPmTimeArray = [Any]()
var combinedArray = [Any]()
var combinedStartAMArray = [Any]()
var combinedEndPMArray = [Any]()
var mergedArray = [Any?]()

最好使用'??'运算符的默认值。例如:daysCombinedFinal = daysCombined[0] as? [Any?] ?? [] - Shubham Naik
假设'daysCombinedFinal'是一个数组。 - Shubham Naik
2
你真的需要带有可选项的数组吗?这就是警告的实际原因。而且,不要使用大多数未指定的 Any,考虑使用更具体的类型。 - vadian
1
你真的不应该使用 Any。尽量保持数组的同质性。 - Fogmeister
@jrturton 你在说什么? :P - Fogmeister
@Fogmeister 我从来没有说过什么。 - jrturton
1个回答

2
您的问题与“可选”和“解包器”的概念有关。以下是两者之间的简要介绍及区别:如何理解Swift中的!? “?(可选)”表示您的变量可能包含空值,而“!(解包器)”表示在运行时使用它(尝试从中获取值)时,您的变量必须具有内存(或值)。
在您的情况下,您正在尝试使用索引号从数组中获取值。现在,您的数组元素类型为“Any”。
因此,数组元素可以包含任何种类的值/信息。如果您尝试强制解包元素的值,并且它不会返回值或类型与您使用解包器进行转换的类型不同,则应用程序将崩溃。
苹果开发者委员会提供了详细的基本教程,请参见此处
此警告提示您,您的应用程序可能会在强制解包可选值时崩溃。
作为解决方案,您应该使用“?(可选)”和“if-let”块,避免强制解包和安全执行代码,例如:
if let daysC = daysCombined[0] as? [Any] {
    daysCombinedFinal = daysC
}

分享完整的源代码,以获得更好的解决方案,因为您在问题中没有分享数组的声明。由于我对可选数组 [Any?] 元素存在疑惑。Swift 不允许数组元素是可选项。
更新:考虑到所有数组的元素都是“字典”,这里删除了从数组分配强制展开的内容。
var daysCombined = [Any]()
var daysCombinedFinal = [Any?]()
daysCombined = [self.combinedArray[indexPath.row]]

// Update 1
// if combinedArray is an array of array
if let arrayElement = daysCombined[0] as? [Any] {
    daysCombinedFinal = arrayElement
}
let str = daysCombinedFinal.flatMap { $0 as? String }.joined(separator:" ")
var startAMCombined = [Any]()
var startAMCombinedFinal = [Any?]()
startAMCombined = [self.combinedStartAMArray[indexPath.row]]

// Update 2
if let arrayElement = startAMCombined[0] as? [Any] {
    startAMCombinedFinal = arrayElement
}
var endPMCombined = [Any]()
var endPMCombinedFinal = [Any?]()
endPMCombined = [self.combinedEndPMArray[indexPath.row]]

// Update 3
if let arrayElement = endPMCombined[0] as? [Any] {
    endPMCombinedFinal = arrayElement
}

cell.operatingDaysLabel.text = str

这里不需要 if-let。可以改为这样做:daysCombinedFinal = daysCombined[0] as? [Any]。 - Robert Gummesson
1
@RobertGummesson 使用 as? [Any] 仍然返回一个可选项。因此,您仍然需要解包它。使用 if let 将解包可选项,以便 daysC 不会成为可选项。 - Fogmeister
同意@Fogmeister - Krunal
@RobertGummesson 请通过编辑此答案提出您的关注。 - Krunal
仍然显示警告...有哪些不明确之处? - Freshley Kremp
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接