【问题标题】:How to stop enumerateObjectsUsingBlock Swift如何停止 enumerateObjectsUsingBlock Swift
【发布时间】:2014-08-04 12:48:21
【问题描述】:

如何停止块枚举?

    myArray.enumerateObjectsUsingBlock( { object, index, stop in
        //how do I stop the enumeration in here??
    })

我知道在 obj-c 中你会这样做:

    [myArray enumerateObjectsUsingBlock:^(id *myObject, NSUInteger idx, BOOL *stop) {
        *stop = YES;
    }];

【问题讨论】:

  • 链接基本上说,不要在swift中使用enumerateObjectsUsingBlock,因为使用for ... in.. enumerate表达功能更好
  • @David:不是重复的。其他线程不覆盖停止参数。
  • 是的,答案是关于如何用新的语法替换这个旧的调用以及如何及早停止它。
  • 如果我们被要求提供有关特定 API 的答案,提供替代选项可能会有所帮助,但从技术上讲这不是答案。只有一种意见。如果你在数学考试中被要求用泰勒计算某个函数,但你使用傅里叶,因为你认为它更好,因为什么原因,那是完全失败的。如果 OP 需要/想要使用 enumerateObjectsUsingBlock,我们不应该强迫他使用其他东西。虽然我们应该提到一个更好的方法。

标签: objective-c nsarray block swift enumeration


【解决方案1】:

只要stop = true

由于 stop 被声明为 inout,swift 会为您处理间接映射。

【讨论】:

  • Cannot assign 'let' value 'stop'
  • 使用stop.memory = true
【解决方案2】:

在 Swift 1 中:

stop.withUnsafePointer { p in p.memory = true }

在 Swift 2 中:

stop.memory = true

在 Swift 3 - 4 中:

stop.pointee = true

【讨论】:

  • 神圣的FSM,为什么这么难做到?我猜是因为你不应该使用 enumerateObjectsUsingBlock 而是 for 废话
  • 因为他们将一些可怕的东西从 Objective-C 桥接到 Swift
  • 因为 Apple 现在建议改用 for (index, value) in array.enumerate(),它完全消除了阻塞和停止,同时更清晰地复制完全相同的功能。
  • @random。如果可以的话,你应该使用 Array,而不是 NSArray 和 for obj in myArray-Syntax。
  • @david: enumerate 是一个全局函数,而不是数组上的方法。它被称为enumerate(array)
【解决方案3】:

接受的答案是正确的,但仅适用于 NSArrays。不适用于 Swift 数据类型 Array。如果您愿意,可以使用扩展程序重新创建它。

extension Array{
    func enumerateObjectsUsingBlock(enumerator:(obj:Any, idx:Int, inout stop:Bool)->Void){
        for (i,v) in enumerate(self){
            var stop:Bool = false
            enumerator(obj: v, idx: i,  stop: &stop)
            if stop{
                break
            }
        }
    }
}

这样称呼

[1,2,3,4,5].enumerateObjectsUsingBlock({
    obj, idx, stop in

    let x = (obj as Int) * (obj as Int)
    println("\(x)")

    if obj as Int == 3{
        stop = true
    }
})

或者对于以块作为最后一个参数的函数

[1,2,3,4,5].enumerateObjectsUsingBlock(){
    obj, idx, stop in

    let x = (obj as Int) * (obj as Int)
    println("\(x)")

    if obj as Int == 3{
        stop = true
    }
}

【讨论】:

  • 它在我的机器上运行。使用 beta 3。
  • @VyachaslavGerchicov 我想你的问题是:“如果它不起作用,为什么会被赞成”。嗯,4年前就有了。 Swift 经历了一些不兼容的变化。随意修复它。
  • @vikingosegundo Cannot assign to value: 'stop' is a 'let' constant。我找到的最简单的解决方案是stop.initialize(to: true)。你知道更好的方法吗?
【解决方案4】:

由于XCode6 Beta4,可以改用以下方式:

let array: NSArray = // the array with some elements...

array.enumerateObjectsUsingBlock( { (object: AnyObject!, idx: Int, stop: UnsafePointer<ObjCBool>) -> Void in

        // do something with the current element...

        var shouldStop: ObjCBool = // true or false ...
        stop.initialize(shouldStop)

        })

【讨论】:

  • 我正要发布一个答案,指出stop[0] = true 有效,但我想我更喜欢stop.initialize(true)。在这个主题上缺乏明确的指导(对于经常使用的模式)有点令人沮丧。
【解决方案5】:

不幸的是,这改变了 Swift 的每个主要版本。这是一个细分:

斯威夫特 1

stop.withUnsafePointer { p in p.memory = true }

斯威夫特 2

stop.memory = true

斯威夫特 3

stop.pointee = true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 2016-12-07
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 2016-02-17
    • 1970-01-01
    相关资源
    最近更新 更多