Swift 还通过要求修改内存中位置的代码具有对该内存的独占访问权,来确保对同一内存区域的多重访问不会产生冲突。由于 Swift 会自动管理内存,因此大多数时候根本不需要考虑内存访问的问题。然而,如果了解什么地方会有潜在的内存冲突发生也是很重要,这样就可以避免写出对内存访问有冲突的代码,如果代码中确实包含冲突,则会出现编译时错误或运行时错误。
二、内存的访问冲突
当执行设置变量的值、将参数传递给函数之类的代码时,访问内存这件事情会就发生。
如下所示的代码包含一个读取操作和一个访问操作:
// A write access to the memory where one is stored.var one =1// A read access from the memory where one is stored.print("We're number \(one)!")
当不同部分的代码试图同时访问同一块内存时,可能会发生内存冲突访问。同时访问同一块内存可能会导致不可预测或不一致的行为。在 Swift 中,有多种方法可以实现在跨越好几行代码的过程下修改某个值,这导致可以实现在修改自身的过程中去尝试访问自己的值。
通常来说,一个读取访问和一个写入访问的区别是很明显的:一个写入访问会改变内存中的位置,但读取访问不会。内存中的位置是指要访问的内容,例如:变量、常量或属性,内存访问可以是瞬时的,也可以是维持一段时间的。如果一个操作仅使用了 C 原子(atomic)操作,则该操作是原子操作,否则就是非原子的;如果某个访问在开始之后和结束之前都无法运行其他代码,那么这个访问就是一个瞬时访问,从本质上来说,两个瞬时访问是不能在同一时间发生的,并且大多数内存访问操作都是瞬时的。
如下所示的代码中读取和写入访问都是瞬时的:
funconeMore(than number:Int)->Int{return number +1}var myNumber =1
myNumber =oneMore(than: myNumber)print(myNumber)// Prints "2"
funcbalance(_ x:inoutInt,_ y:inoutInt){let sum = x + y
x = sum /2
y = sum - x
}var playerOneScore =42var playerTwoScore =30balance(&playerOneScore,&playerTwoScore)balance(&playerOneScore,&playerOneScore)// Error: conflicting accesses to playerOneScore
structPlayer{var name:Stringvar health:Intvar energy:Intstaticlet maxHealth =10mutatingfuncrestoreHealth(){
health =Player.maxHealth
}}
在上面的 restoreHealth() 方法中,对 self 的写入访问从该方法的开头开始,一直持续到该方法返回为止。在这种情况下,restoreHealth() 中没有其他代码可以重叠访问 Player 实例的属性。如下的 shareHealth(with:) 方法将另一个 Player 实例用作 in-out 参数,从而可能导致访问重叠:
extensionPlayer{mutatingfuncshareHealth(with teammate:inoutPlayer){balance(&teammate.health,&health)}}var oscar =Player(name:"Oscar", health:10, energy:10)var maria =Player(name:"Maria", health:5, energy:10)
oscar.shareHealth(with:&maria)// OK
在上面的示例中,调用 Oscar 与 Maria 共享生命值的 shareHealth(with:) 方法不会引起冲突。在方法调用过程中,对 oscar 有写入访问,因为 oscar 是 mutating 方法中 self 的值,并且与 maria 的写入访问的持续时间是一致的,因为 maria 是作为 in-out 参数传递的。如下所示,可以看到它们访问内存中的不同位置,因此即使两个写访问在时间上重叠,也不会冲突:
但是,如果传递一个 oscar 作为 shareHealth(with:) 的参数,就会产生冲突:
oscar.shareHealth(with:&oscar)// Error: conflicting accesses to oscar
var playerInformation =(health:10, energy:20)balance(&playerInformation.health,&playerInformation.energy)// Error: conflicting access to properties of playerInformation
xml帮助类在最后
刚好有业务需要解析xml文件,于是找到帮助类代码开始尝试解析文件,总是出现异常:<xml xmlnsxxxxxxxxxxxxxxxx> was not expected,开始寻找解决方案:
要使结果正确,必须满足两个条件…
简介
关于QString乱码的一些补充。主要就两点,QChar、QString底层存储的字符都是16进制的Unicode编码。
QChar QChar对应16位的Unicode字符集。 The QChar class provides a 16-bit Unicode character. In Qt, Unicode characters are 16-bit entities without an…