- 内存访问分为读写,在以下三种条件同时满足时会造成内存访问冲突。
1.至少一个是写
2.访问同一块地址
3.访问期间重叠 - 内存访问又分为立即访问(大多数情况),和长期访问。造成访问冲突主要由函数的in-out参数和结构体的mutating方法造成。
- 原值作为inout进行写入时,你不能够访问该原值。实例如下:
number和stepSize指向同一块地址,读写访问同时发生,会访问冲突var stepSize = 1 func incrementInPlace(_ number: inout Int) { number += stepSize } incrementInPlace(&stepSize)
解决方案如下:// Make an explicit copy. var copyOfStepSize = stepSize incrementInPlace(©OfStepSize) // Update the original. stepSize = copyOfStepSize
- 函数需要传入多个inout类型参数时,不能传入同一变量。实例如下:
报错inout参数不能传入别名一样。跟函数体无关,即使函数体内为空也会报错。func balance(_ x: inout Int, _ y: inout Int) { let sum = x + y x = sum / 2 y = sum - x } var playerOneSorce = 42 var playerTwoSorce = 30 balance(&playerOneSorce, &playerTwoSorce) //balance(&playerOneSorce, &playerOneSorce) error
- inout作为参数表示整个函数都是该变量的访问期间。所以前一例在长期写访问同时进行了读访问。后一例对同一变量同时进行两次长期写访问。
- 同时注意省略Inout的方法,通过在调用时使用&取地址分辨。
- 注意self所代表实例与传入参数相同造成的访问冲突。如下:
前者为同时对oscar和maria进行写操作,没问题。后者同时对oscar进行写操作,会造成错误。struct Player { var name: String var health: Int var energy: Int static let maxHealth = 10 mutating func restoreHealth(){ health = Player.maxHealth } } extension Player { mutating func shareHealth(with teamate: inout Player) { balance(&teamate.health, &health) } } var oscar = Player.init(name: "Oscar", health: 10, energy: 10) var maria = Player.init(name: "Maria", health: 5, energy: 5) oscar.shareHealth(with: &maria) print(oscar.health) //oscar.shareHealth(with: &oscar)
- 对于结构体枚举的属性以及元组的元素来说,对其进行写操作等同于对整个类型进行写操作,一样会造成冲突,由于其是值类型造成的。如下:
对元组同时进行写操作var playerInformation = (health: 10, energy: 20) balance(&playerInformation.health, &playerInformation.energy)
对结构体同时进行写操作var holly = Player(name: "Holly", health: 10, energy: 10) balance(&holly.health, &holly.energy)
- 注意以上的错误针对于全局变量,对于局部变量则没事,如下:
func someFunction() { var oscar = Player(name: "Oscar", health: 10, energy: 10) balance(&oscar.health, &oscar.energy) // OK }
- swift提供了一些可以保证内存安全的措施,当满足以下时
1.访问实例存储属性,而非类属性或计算属性
2.结构体是局部变量,非全局变量
3.结构体不被闭包捕捉,或被非逃逸闭包捕捉
Memory Safety
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
推荐阅读更多精彩内容
- 2016年国庆假期终于把此书过完,整理笔记和体会于此。 关于书名 书名源于俄罗斯的演员斯坦尼斯拉夫斯基创作的《演员...