dispatch_async 更新变量崩溃 - 线程安全
dispatch_async update variable crash - thread safety
当我 运行 以下代码多次应用程序崩溃时:
res.append(i)
错误是致命错误:UnsafeMutablePointer.destroy 计数为负数
要么
正在释放的指针未分配 *** 在 malloc_error_break 中设置断点以调试
在dispatch_async里面更新一个全局变量不对吗?
class ViewController: UIViewController {
var result = Array<Int>()
func method(completion: (inner: () throws -> String)->Void){
let group:dispatch_group_t = dispatch_group_create();
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var res = Array<Int>()
for i in 0..<4 {
dispatch_group_async(group,queue){
res.append(i)
print(res)
print("Block\(i)");
var s = 0
for k in 0..<1000 {
s = 2+3
}
print("Block\(i)End");
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
print("All background tasks are done!!");
print(res)
}
override func viewDidLoad() {
super.viewDidLoad()
self.method() { (inner: () throws -> String) -> Void in
do {
let res = try inner()
print(res)
} catch let error {
print(error)
}
}
}
是的,Array
不是线程安全的,所以写入数组时,应该确保atomic
。
所以可以加高性能锁:dispatch_semaphore_t.
func method(completion: (inner: () throws -> String)->Void){
// add lock
let lock: dispatch_semaphore_t = dispatch_semaphore_create(1)
let group:dispatch_group_t = dispatch_group_create();
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var res = Array<Int>()
for i in 0 ..< 5 {
dispatch_group_async(group,queue){
// lock
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)
res.append(i)
// unlock
dispatch_semaphore_signal(lock)
var s = 0
for k in 0..<1000 {
s = 2+3
}
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
print("All background tasks are done!!");
print(res)
}
但是注意,如果你的异步任务不是像上面这样的耗时操作,请不要使用多线程,因为线程调度很耗时,可能会导致性能损失。
当我 运行 以下代码多次应用程序崩溃时:
res.append(i)
错误是致命错误:UnsafeMutablePointer.destroy 计数为负数 要么 正在释放的指针未分配 *** 在 malloc_error_break 中设置断点以调试
在dispatch_async里面更新一个全局变量不对吗?
class ViewController: UIViewController {
var result = Array<Int>()
func method(completion: (inner: () throws -> String)->Void){
let group:dispatch_group_t = dispatch_group_create();
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var res = Array<Int>()
for i in 0..<4 {
dispatch_group_async(group,queue){
res.append(i)
print(res)
print("Block\(i)");
var s = 0
for k in 0..<1000 {
s = 2+3
}
print("Block\(i)End");
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
print("All background tasks are done!!");
print(res)
}
override func viewDidLoad() {
super.viewDidLoad()
self.method() { (inner: () throws -> String) -> Void in
do {
let res = try inner()
print(res)
} catch let error {
print(error)
}
}
}
是的,Array
不是线程安全的,所以写入数组时,应该确保atomic
。
所以可以加高性能锁:dispatch_semaphore_t.
func method(completion: (inner: () throws -> String)->Void){
// add lock
let lock: dispatch_semaphore_t = dispatch_semaphore_create(1)
let group:dispatch_group_t = dispatch_group_create();
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var res = Array<Int>()
for i in 0 ..< 5 {
dispatch_group_async(group,queue){
// lock
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER)
res.append(i)
// unlock
dispatch_semaphore_signal(lock)
var s = 0
for k in 0..<1000 {
s = 2+3
}
}
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
print("All background tasks are done!!");
print(res)
}
但是注意,如果你的异步任务不是像上面这样的耗时操作,请不要使用多线程,因为线程调度很耗时,可能会导致性能损失。