In Chapters 5- concurrent problems: Dispatch Barrier, it is mentioned that:
’Notice how you’re now specifying that you want a concurrent queue and that the writers should be implemented with a barrier The barrier task won’t occur until all of the previous reads have completed.
“Once the barrier hits, the queue expectations that it’s serial and only the barrier task can run until completion. Once it completes, all tasks that were submitted after the barrier task can continue to run consistently.”“
This description does not match the demonstration I wrote when printing. The print shows that the closure in queue. sync (flags:. barrier) has been executed, but the execution has not been completed. Instead, the data is being read. What is the problem. This is an example I wrote and printed:
class Image {
let name: String
init(name: String) {
self.name = name
}
}
class BarrierImages {
private let queue = DispatchQueue(label: "...", attributes: .concurrent)
private var _images: [Image] = []
init(_images: [Image]) {
self._images = _images
}
var images: [Image] {
var copied: [Image] = []
queue.sync {
copied = _images
}
return copied
}
func add(image: Image) {
print("call add method \(image.name)")
queue.sync(flags: .barrier) { [weak self] in
print("adding \(image.name)")
self?._images.append(image)
print("added \(image.name)")
}
}
func remove(at index: Int) -> Image? {
var removed: Image?
queue.sync(flags: .barrier) { [weak self] in
removed = self?._images.remove(at: index)
}
return removed
}
}
let barrierImages = BarrierImages(_images: Array(1 ..< 6).map { i in
Image(name: "init image\(i)")
})
let queue = DispatchQueue(label: "com.test.queue", attributes: .concurrent)
let group = DispatchGroup()
queue.async(group: group) {
for image in barrierImages.images {
print("fitst task image:\(image.name)")
}
}
queue.async(group: group) {
for image in barrierImages.images {
print("second task image:\(image.name)")
}
}
for i in 0 ..< 5 {
let image = Image(name: "image\(i)")
barrierImages.add(image: image)
}
queue.async(group: group) {
for image in barrierImages.images {
print("third image:\(image.name)")
}
}
queue.async(group: group) {
for image in barrierImages.images {
print("fourth image:\(image.name)")
}
}
group.wait()
print(barrierImages.images)
print(barrierImages.images.count)
This is printing
call add method image0
adding image0
fitst task image:init image1
fitst task image:init image2
fitst task image:init image3
fitst task image:init image4
fitst task image:init image5
added image0
second task image:init image1
call add method image1
second task image:init image2
adding image1
second task image:init image3
second task image:init image4
second task image:init image5
second task image:image0
added image1
call add method image2
adding image2
added image2
call add method image3
adding image3
added image3
call add method image4
adding image4
added image4
third image:init image1
third image:init image2
third image:init image3
third image:init image4
third image:init image5
third image:image0
third image:image1
third image:image2
third image:image3
third image:image4
fourth image:init image1
fourth image:init image2
fourth image:init image3
fourth image:init image4
fourth image:init image5
fourth image:image0
fourth image:image1
fourth image:image2
fourth image:image3
fourth image:image4
[__lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image, __lldb_expr_429.Image]
10