计算属性getter出错

时间:2017-05-02 04:16:45

标签: ios swift computed-properties

我在iOS Swift 3应用程序中有以下计算属性。

var countItems:[Int] {// Count the interesting items.
    var countResult = [Int]()
    for i in 0..<size {
        var count = 0
        for j in i*size..<(i+1)*size {
            if binaryArray?[j] == true {count += 1}
        }
        countResult.append(count)
    }
    return countResult
}

99.9%的时间完美运行。 但是这条消息让我崩溃了:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x16fc7bff0)
    frame #0: 0x000000018f2d95b8 libsystem_malloc.dylib`malloc_zone_malloc
    frame #1: 0x000000018f2dc56c libsystem_malloc.dylib`malloc + 32
    frame #2: 0x0000000100964048 libswiftCore.dylib`swift_slowAlloc + 12
    frame #3: 0x000000010096409c libswiftCore.dylib`_swift_allocObject_ + 28
    frame #4: 0x0000000100f6cd50 libswiftSwiftOnoneSupport.dylib`generic specialization <preserving fragile attribute, Swift._ArrayBuffer<Swift.Double> with Swift._ArrayBuffer<Swift.Double> : Swift._ArrayBufferProtocol in Swift> of (extension in Swift):Swift._ArrayBufferProtocol._forceCreateUniqueMutableBuffer (countForNewBuffer : Swift.Int, minNewCapacity : Swift.Int) -> Swift._ContiguousArrayBuffer<A.Element> with unmangled suffix "_merged" + 84
    frame #5: 0x0000000100f69d5c libswiftSwiftOnoneSupport.dylib`generic specialization <preserving fragile attribute, Swift.String.CharacterView> of Swift.Array._copyToNewBuffer (oldCount : Swift.Int) -> () with unmangled suffix "_merged" + 76
    frame #6: 0x0000000100f655bc libswiftSwiftOnoneSupport.dylib`generic specialization <preserving fragile attribute, Swift.UInt64> of Swift.Array.append (A) -> () with unmangled suffix "_merged" + 124
  * frame #7: 0x0000000100103078 MyApp`TheClass.countItems.getter(self=MyApp.TheClass @ 0x000000016fc7c260) at TheClass.swift:31
    frame #8: 0x0000000100138354 MyApp`TheClass.callingFunction(self=0x000000010201d930) -> Bool at TheClass.swift:2343

我想知道计算属性本身是否存在问题(我看不到)或者外面是否有问题。 如果有人有线索,我会很高兴。 提前感谢任何相关提示。

作为参考,这是另一个带有较短消息的崩溃:

(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x16fc27fb0)
    frame #0: 0x00000001001567bc MyApp`TheClass.countItems.getter(self=MyApp.TheClass @ 0x000000016fc27fb0) at TheClass.swift:0
  * frame #1: 0x000000010018c2e4 MyApp`TheClass.callingFunction(self=0x000000010200c730) -> Bool at TheClass.swift:2348

2 个答案:

答案 0 :(得分:0)

请尝试在后台线程中进行工作,因为您似乎在主线程上进行了所有数字处理,这是不好的。

要么你可以创建一个返回整数项数组的函数。这将在后台线程中处理数组。

因为我不知道什么是 binaryArray 变量。如果你需要,你可以通过。

SWIFT 3.0:

func countItems(_ size : Int, completion: ([Int])) {
    let queue = DispatchQueue.global(qos: .background)
    queue.async {
        var countResult = [Int]()
        for i in 0..<size {
            var count = 0
            for j in i*size..<(i+1)*size {
                if self.binaryArray?[j] == true {count += 1}
            }
            countResult.append(count)
        }
        completion(countResult) 
    }
}

答案 1 :(得分:0)

第一个堆栈跟踪明显位于Array.append方法内,顶部有malloc个调用。因此,您可能会在Swift Array实现中遇到内部错误,可能是在其动态内存管理代码上。

假设这是真的,尝试在启动算法之前在一次分配必要的数组容量:

var countResult = [Int]()
countResult.reserveCapacity(size)
  

如果要向数组添加已知数量的元素,请使用reserveCapacity以避免多次重新分配。此方法确保数组具有唯一的,可变的,连续的存储,并为至少所请求的元素数分配空间。

作为奖励,您可能会对size的大值获得良好的性能提升:)