快速 setter 导致 exc_bad_access

标签 swift exc-bad-access setter

下面我有一个简单的类(class)

import Foundation

public class UsefulClass: NSObject{
    var test:NSNumber{
        get{return self.test}
        set{
            println(newValue)
            self.test = newValue
        }
    }
    override init() {
        super.init()
        self.test = 5;
    }
}

我在这里初始化它

import UIKit

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        var testClass = UsefulClass()
    }
}

但是它会导致 xcode 打印出 200 个 5,然后由于 EXC_BAD_ACCESS code = 2 而崩溃。为什么会发生这种情况?

最佳答案

@vadian 在他的回答中提供了一个解决方案,应该可以解决您的问题。让我解释一下发生了什么。

您创建了一个计算属性,即不受变量支持的属性,取而代之的是 getter 和 setter 通常对另一个存储的属性进行一些处理,以便分别返回一个值并设置一个新值.

这是您的计算属性:

var test: NSNumber {
    get { return self.test }
    set {
        println(newValue)
        self.test = newValue
    }
}

查看 getter 实现:

return self.test

它有什么作用?它读取当前实例的 test 属性并返回它。哪个是 test 属性?就是这个:

var test: NSNumber {
    get { return self.test }
    set {
        println(newValue)
        self.test = newValue
    }
}

是的,这是同一个属性。你的 getter 所做的就是递归地、无限期地调用自身,直到运行时发生崩溃。

同样的规则适用于 setter:

self.test = newValue 

它不断调用自身,直到应用程序崩溃。

关于快速 setter 导致 exc_bad_access,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34227521/

相关文章:

ios - 如何在 Swift 中正确使用类扩展?

iphone - 插入 subview 时EXC_BAD_ACCESS? (iPhone)

optimization - 在 Getter/Setter 或其他地方进行数据验证?

ruby - 在 Ruby 中创建一个接受额外参数的 setter 方法

ios - 在 Swift 中写入 Google 表格

ios - 如何让 "Center location on Map"工作?

swift - 实时数据库 - 如何更改安全规则以检查用户名是否存在

ios - NSManagedObject 在 Swift 中实现协议(protocol)的 EXC_BAD_ACCESS 错误

c - 为什么我要 exc_bad_access 进行强制转换?

java - 填充时只设置从表单到操作的最后一个参数,为什么?