物业获取者和二传手

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了物业获取者和二传手相关的知识,希望对你有一定的参考价值。

有了这个简单的类,我得到编译器警告

试图在自己的setter / getter中修改/访问x

当我像这样使用它时:

var p: point = Point()
p.x = 12

我得到一个EXC_BAD_ACCESS。如果没有明确支持ivars,我怎么能这样做呢?

class Point {

    var x: Int {
        set {
            x = newValue * 2 //Error
        }
        get {
            return x / 2 //Error
        }
    }
    // ...
}
答案

塞特斯和吸气者适用于computed properties;这样的属性在实例中没有存储 - 来自getter的值应该从其他实例属性计算。在您的情况下,没有分配x

明确地说:“如果没有明确的支持ivars我怎么能这样做”。你不能 - 你需要一些东西来备份计算属性。试试这个:

class Point {
  private var _x: Int = 0             // _x -> backingX
  var x: Int {
    set { _x = 2 * newValue }
    get { return _x / 2 }
  }
}

具体来说,在Swift REPL中:

 15> var pt = Point()
pt: Point = {
  _x = 0
}
 16> pt.x = 10
 17> pt
$R3: Point = {
  _x = 20
}
 18> pt.x
$R4: Int = 10
另一答案

这是一个理论上的答案。这可以找到here

{get set}属性不能是常量存储属性。它应该是一个计算属性,并且应该实现get和set。

另一答案

Swift中的Setter / getters与ObjC完全不同。该属性成为计算属性,这意味着它没有像在ObjC中那样的_x等支持变量。

在下面的解决方案代码中,您可以看到xTimesTwo不存储任何内容,而只是计算x的结果。

Official docs on computed properties

您想要的功能也可能是Property Observers

你需要的是:

var x:Int

var xTimesTwo:Int {
    set {
       x = newValue / 2
    }
    get {
        return x * 2
    }
}

您可以修改setter / getters中的其他属性,这就是它们的用途。

另一答案

您可以使用属性观察者自定义设置值。要做到这一点,请使用'didSet'而不是'set'。

class Point {

var x:Int {
    didSet {
        x = x * 2
    }
}
...

至于吸气...

class Point {

var doubleX: Int {
    get {
        return x / 2
    }
}
...
另一答案

详细说明GoZoner的答案:

这里你真正的问题是你递归地调用你的getter。

var x:Int
    {
        set
        {
            x = newValue * 2 // This isn't a problem
        }
        get {
            return x / 2 // Here is your real issue, you are recursively calling 
                         // your x property's getter
        }
    }

就像上面的代码注释所示,你无限地调用x属性的getter,它将继续执行,直到你得到一个EXC_BAD_ACCESS代码(你可以在Xcode的游乐场环境的右下角看到微调器)。

考虑一下Swift documentation的例子:

struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 0.0, height = 0.0
}
struct AlternativeRect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set {
            origin.x = newValue.x - (size.width / 2)
            origin.y = newValue.y - (size.height / 2)
        }
    }
}

注意中心计算属性永远不会在变量的声明中修改或返回自身。

另一答案

为了替换快速变量的settergetter,请使用下面给出的代码

var temX : Int? 
var x: Int?{

    set(newX){
       temX = newX
    }

    get{
        return temX
    }
}

我们需要将变量的值保存在临时变量中,因为尝试访问其getter / setter被覆盖的同一变量将导致无限循环。

我们可以像这样调用setter

x = 10

在给定的代码行下面将触发Getter

var newVar = x
另一答案

你用x递归地定义x。好像有人问你你多大了?你回答“我是我的两倍”。这没有意义。

你必须说我是约翰的年龄或任何其他变量,但你自己。

计算变量总是依赖于另一个变量。


拇指规则永远不会从吸气剂即get中获取属性本身。因为这会引发另一个触发另一个的get。 。 。甚至不打印。因为打印还需要在打印之前“获取”该值!

struct Person{
    var name: String{
        get{
            print(name) // DON'T do this!!!!
            return "as"
        }
        set{
        }
    }
}

let p1 = Person()

因为这会发出以下警告:

试图从它自己的getter中访问'name'。

该错误看起来像这样模糊:

enter image description here

作为替代方案,您可能想要使用didSet。使用didSet,您将获得之前设置的值,并且设置为。有关更多信息,请参阅this answer

另一答案

更新:Swift 4

在下面的类中,setter和getter应用于变量sideLength

class Triangle: {
    var sideLength: Double = 0.0

    init(sideLength: Double, name: String) { //initializer method
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }

    var perimeter: Double {
        get { // getter
            return 3.0 * sideLength
        }
        set { //setter
            sideLength = newValue / 4.0
        }
   }

创建对象

var triangle = Triangle(sideLength: 3.9, name: "a triangle")

消气

print(triangle.perimeter) // invoking getter

二传手

triangle.perimeter = 9.9 // invoking setter
另一答案

试试这个:

var x:Int!

var xTimesTwo:Int {
    get {
        return x * 2
    }
    set {
        x = newValue / 2
    }
}

这基本上就是Jack Wu的答案,但不同的是,在Jack Wu的回答中他的x变量是var x: Int,在我的中,我的x变量是这样的:var x: Int!,所以我所做的只是让它成为一个可选类型。

另一答案

Swift中的setter和getter适用于计算属性/变量。这些属性/变量实际上并不存储在内存中,而是基于存储的属性/变量的值进行计算。

请参阅Apple关于此主题的Swift文档:Swift Variable Declarations

以上是关于物业获取者和二传手的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 http 请求在 Instagram 中获取关注者和关注列表

小区物业管理系统-照片存取

使用 Instagram API 获取关注者和关注者

私人和受保护财产的获取者和设置者

如何在新的 Spotify Web api 上获取用户的关注者和用户的关注用户?

DriveApp |获取文件的查看者和评论者