I run the following code in an actor:
func aaa() async throws -> Data {
async let result = Task(
operation: {
... decompressing data through try (data as NSData).decompressed(using: .lzfse) as Data
}
).result
switch await result {
case .success(let value): return value
case .failure(let error): throw error
}
I do it this way because I do not want to block the actor by decompression, and there is no state change in the actor afterwards. I would say that the actor plays no significant role here. Important is that many (14) concurrent tasks run in parallel, however NOT on the same data. It runs fine for a while (dozens/hundreds of data decompressed), and then the following happens:
Activity Monitor (macOS GUI tool) shows almost none User CPU time, and approx. 75% System CPU time. The rest is idle. (When it runs fine, User CPU time is 95+%)
When I pause the run in Xcode (in release config it behaves the same), all threads are in mach_msg2_trap
#0 0x0000000180ac21f4 in mach_msg2_trap ()
#1 0x0000000180ad4b24 in mach_msg2_internal ()
#2 0x0000000180ac52fc in vm_copy ()
#3 0x0000000180916b78 in szone_realloc ()
#4 0x000000018093cfb0 in _malloc_zone_realloc ()
#5 0x000000018093d7e8 in _realloc ()
#6 0x0000000180bb8a10 in __CFSafelyReallocate ()
#7 0x0000000181d00e30 in _NSMutableDataGrowBytes ()
#8 0x0000000181ce2630 in -[NSConcreteMutableData appendBytes:length:] ()
#9 0x00000001823c30d8 in -[_NSDataCompressor processBytes:size:flags:] ()
#10 0x00000001823c32c4 in -[NSData(NSDataCompression) _produceDataWithCompressionOperation:algorithm:handler:] ()
#11 0x00000001823c3598 in -[NSData(NSDataCompression) _decompressedDataUsingCompressionAlgorithm:error:] ()
It looks like something is wrong with safe reallocation, however if this have been a bug, then all macOS is stuck.
Any idea, please?
Post
Replies
Boosts
Views
Activity
I need to optimize my SwiftUI code, and views conforming to Equatable seem to a good way forward. However, I have some questions, that could be also an interest of others.
View can conform to Equatable, and NOT encapsulated in EquatableView nor .equatable() view modifier, and modern SwiftUI implementations still can use the Equatable functionality, right?
When view contains @ObservedObject or @EnvironmentObject, then static func == (...) have to handle the changes of the observed objects, otherwise the view is not updated after the observed object published change. At least this is my experience. Correct?
Does view, that is Equatable, need to care about equality of its subviews? I hope no. I hope that view can evaluate equality only based on properties available to it, and SwiftUI takes responsibility for its subviews. I. e.: Even when some view returns true on ==, but something changes in its subview (detail hidden to the view), SwiftUI is able to recognize the change and takes appropriate actions. Correct?
When view returns true on equality check (==), but some environment value changes (not visible to the view), the view still reflects the change. Correct?
When the observed object conforms to Equatable, it is being used by SwiftUI. For what purpose? In most (if not all) cases, lhs and rhs are the same instance, so == returns true.
This code can be compiled as command line tool for macOS.
import Foundation
@main
struct App {
static var counter = 0
static func main() async throws {
print("Thread: \(Thread.current)")
let task1 = Task { @MainActor () -> Void in
print("Task1 before await Task.yield(): \(Thread.current)")
await Task.yield()
print("Task1 before await increaseCounter(): \(Thread.current)")
await increaseCounter()
print("Task1 after await increaseCounter(): \(Thread.current)")
}
let task2 = Task { @MainActor () -> Void in
print("Task2 before await Task.yield(): \(Thread.current)")
await Task.yield()
print("Task2 before await decreaseCounter(): \(Thread.current)")
await decreaseCounter()
print("Task2 after await decreaseCounter(): \(Thread.current)")
}
_ = await (task1.value, task2.value)
print("Final counter value: \(counter)")
}
static func increaseCounter() async {
for i in 0..<999 {
counter += 1
print("up step \(i), counter: \(counter), thread: \(Thread.current)")
await Task.yield()
}
}
static func decreaseCounter() async {
for i in 0..<999 {
counter -= 1
print("down step \(i), counter: \(counter), thread: \(Thread.current)")
await Task.yield()
}
}
}
My understanding is:
static func main() async throws inherits MainActor async context, and should always run on the main thread (and it really seems that it does so)
Task is initialized by the initializer, so it inherits the actor async context, so I would expect that will run on the main thread. Correct?
Moreover, the closure for Task is annotated by @MainActor, so I would even more expect it will run on the main thread.
I would expect that static func main() async throws inherits MainActor async context and will prevent data races, so the final counter value will always be zero. But it is not.
Both task1 and task2 really start running on the main thread, however the async functions increaseCounter() and decreaseCounter() run on other threads than the main thread, so the Task does not prevent data races, while I would expect it.
When I annotate increaseCounter() and decreaseCounter() by @MainActor then it works correctly, but this is what I do not want to do, I would expect that Task will do that.
Can anyone explain, why this works as it does, please?
Is there any change in Swift, so this:
guard
let thisDataSource = tableView.dataSource as? Self<SectionIdentifierType, ItemIdentifierType, EquatableCellContent>,
let cell = cellProvider(tableView, indexPath, itemIdentifier)
else { return nil }
cannot be compiled in the XCode 13 beta 5? This works with XCode 12, but the XCode 13 beta 5 does not compile, and says: Error: Cannot specialize Self
(I have created feedback about this too, but my experience with resolving feedbacks is not the best...)
The code is the example example in https://github.com/hibernat/DiffableWithReload
Do I am the only person seeing malfunctioning document tabs?
Sometimes, but often enough, the document tabs stop to work correctly: name of the document tab is still the same, but the tab shows content of another file
the same file is opened in more document tabs
This is so annoying and frustrating that I had to disable document tabs.
Nobody else has the same troubles? Now is available Xcode 12.4 and this is still persisting bug. At least in my project...