Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
由于两个存储属性不’;在Swift中不能以任何方式进行交互?_Swift - Fatal编程技术网

由于两个存储属性不’;在Swift中不能以任何方式进行交互?

由于两个存储属性不’;在Swift中不能以任何方式进行交互?,swift,Swift,我试图理解Swift中的记忆安全,我对两种情况感到困惑 正如我标记的MARK1:-在方法中对self的访问冲突部分是有意义的。两个写访问使彼此重叠。编译器在运行前已给我错误: 重复访问“robGlobal”,但修改需要独占访问;考虑复制到局部变量 问题一:好的,但是关于标记2部分呢?Swift编译器进行了一些优化,以解决struct的写入访问问题 苹果公司解释解决方案如下,但我不清楚 编译器可以证明内存安全性得到了保护,因为这两个存储的属性不会以任何方式交互 问题二:通过在此处创建全局运行时,

我试图理解Swift中的记忆安全,我对两种情况感到困惑

正如我标记的MARK1:-在方法中对self的访问冲突部分是有意义的。两个写访问使彼此重叠。编译器在运行前已给我错误:

重复访问“robGlobal”,但修改需要独占访问;考虑复制到局部变量


问题一:好的,但是关于标记2部分呢?Swift编译器进行了一些优化,以解决struct的写入访问问题

苹果公司解释解决方案如下,但我不清楚

编译器可以证明内存安全性得到了保护,因为这两个存储的属性不会以任何方式交互

问题二:通过在此处创建全局运行时,问题得以解决。但我想知道怎么做?还有为什么它不适用于MARK1部分,为什么


PS:

使用
robGlobal.someFunction()
,您正在对
robLocal
的单独本地实例调用
shareHealth
。显然,在这种情况下没有内存安全问题

但是使用
robGlobal.anotherFunction()
,您随后调用了
robGlobal
的一个实例方法,但随后将对同一
robGlobal
的另一个引用传递到
shareHealth
,因此内存安全冲突

但这很好。这在功能上等同于内存安全检查保护您免受的其他尝试之一:

import UIKit

var robGlobal = Player(name: "Rob", health: 10, energy: 10)
var matt = Player(name: "Matt", health: 5, energy: 10)


struct Player {
    var name: String
    var health: Int
    var energy: Int
    
    static let maxHealth = 10
    mutating func restoreHealth() {
        health = Player.maxHealth
    }
    
    func balance(_ x: inout Int, _ y: inout Int) {
        let sum = x + y
        x = sum / 2
        y = sum - x
    }
    
}

class ViewController: UIViewController {
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        
        //MARK1: -Conflicting Access to self in Methods
        
        robGlobal.shareHealth(with: &matt)
        
        robGlobal.shareHealth(with: &robGlobal) // NOT OK in compile time Error: //Overlapping accesses to 'robGlobal', but modification requires exclusive access; consider copying to a local variable
        
        var robNewLocal = Player(name: "Rob", health: 10, energy: 10)
        
        robNewLocal.shareHealth(with: &robNewLocal) // NOT OK in compile time
        
        
        //MARK2: -Conflicting Access to properties in Methods
        
        robGlobal.someFunction()  // OK
        
        robGlobal.anotherFunction() // NOT OK in Run Time Error: Thread 1: Simultaneous accesses to 0x108cc4050, but modification requires exclusive access
        
    }
}


extension Player {
    mutating func shareHealth(with teammate: inout Player) {
        balance(&teammate.health, &health)
        
    }
    func someFunction() {
        var robLocal = Player(name: "Rob", health: 10, energy: 10)
        balance(&robLocal.health, &robLocal.energy)  // OK
    }
    
    func anotherFunction() {
        balance(&robGlobal.health, &robGlobal.energy)  // NOT OK in Run Time
    }
}
整个想法是与其他玩家共享健康。撇开记忆安全检查不谈,与自己分享一名玩家的健康状况意味着什么?你目前的健康状况是11岁。然后你自己“分享”它。那么,你现在的健康状况如何?还是6号?你的健康状况是11岁,而现在在你与自己分享之后,它的价值变小了,这有意义吗?与自己分享的想法毫无意义。“内存安全”检查可以保护您免受此类误用


就我个人而言,我会的

  • 使
    balance
    成为
    static
    方法,因为它所做的一切都是“平衡”两个整数值,而不是对当前实例做任何事情

  • 这也可能是私有的,因为不需要公开这个函数;及

  • 既然你似乎想“分享健康”来平衡两个玩家之间的健康,以及平衡一个给定玩家的健康和能量,我会写这两种方法

因此,我们最终得出如下结论:

struct播放器{
变量名称:String
变量健康:Int
无功能量:Int
静态let maxHealth=10
}
//标记:-接口
分机{
变异功能恢复健康(){
health=Player.maxHealth
}
变异func shareHealth(队友:inout玩家){
自我平衡(和队友健康和健康)
}
突变功能平衡健康与能量(){
自我平衡(健康和精力)
}
}
//MARK:-专用实用程序方法
专用扩展播放器{
静态函数平衡(x:inout Int,y:inout Int){
设和=x+y
x=总和/2
y=和-x
}
}
然后,您可以执行以下操作:

func someFunction(){
var rob=玩家(名字:“rob”,生命值:20,能量值:10)
rob.balanceHealthAndEnergy()
}
func另一个函数(){
var rob=玩家(名字:“rob”,生命值:10,能量值:10)
var matt=玩家(名字:“matt”,生命值:5,能量值:10)
rob.shareHealth(带:&matt)
}
这个新的界面(共享健康和平衡健康与能源)简化了界面。您可以在本地变量或属性(或者全局变量,如果您真的愿意的话;但是使用全局变量通常是个坏主意)上调用它们。但是你永远不会与自己分享健康,既然平衡是私人的,它就可以最大限度地减少你问题中提到的误用


FWIW,我不会让这些测试方法成为
Player
的实例方法,因为它们没有对当前实例做任何事情。你可以让它们成为静态的方法。或者,您可以在您的模型(或测试或其他)中创建这些方法。但是它们作为
Player
实例方法没有意义。

请不要结束这个问题。如果你觉得不清楚,我可以再详细解释一下。我不清楚问题是什么,因为错误看起来很清楚。您正在对对象调用一个mutating方法,同时还将结构作为参数传递。那么问题是什么呢?@Rob我真的很想知道func someFunction()怎么行。。我正在传递相同的对象(相同的内存位置),但编译不抱怨并且正在工作。。那么引擎盖下发生了什么。。我读了你的相关答案,但无法理解这个例子使本地实例(放在函数中)有多不同?请检查anotherFunction()(使用全局实例)是否正常工作,因此我很困惑“您正在对对象调用一个变异方法,同时还将结构作为参数传递”——someFunction没有执行相同的操作?Swift Memory Access文档中的属性访问冲突部分解释了我的问题,但无法理解,也许您可以更清楚地解释。谢谢你,你的回答很好。在你说“环球旅行通常是个坏主意”之后,我现在问自己。我想你需要问一个新问题this@DrainOpener-我会在谷歌上搜索“全球都是邪恶的”,你会看到大量点击。这个话题已经在这里和互联网上的其他地方讨论过了,如果你不研究它,你的问题就不会受到欢迎(坦率地说,常规搜索无疑会消除n
robGlobal.shareHealth(with: &robGlobal)