Post marked as Apple Recommended
How do I set the tooltip for an AppKit SwiftUI view?
The following code allocates a bunch of big structs in dispatch queues, and it crashes consistently for me when using DispatchQueue.concurrentPerform or NSArray.enumerateObjects, but not when just executing on a background queue.Is there some queue-specific stack-size limit that can be adjusted?import Dispatch
import Foundation
import XCTest
class QueueMemoryAllocCrashTest : XCTestCase {
/// Eight is enough
struct OctoThing {
let t1, t2, t3, t4, t5, t6, t7, t8: T
}
/// A 32K block of memory
struct MemoryChunk {
let chunk: OctoThing<octothing<octothing<octothing>>>? = nil // 32,768 bytes
}
/// This function does nothing but waste stack space (491,520 bytes to be specific)
func wasteMemory() {
// any fewer than 15 of these and the test will pass
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
let _ = MemoryChunk()
}
func testWasteOnQueue() {
// this passes without any problems
DispatchQueue.global(qos: .userInteractive).sync(execute: {
wasteMemory()
wasteMemory()
wasteMemory()
})
}
func testWasteWithConcurrentPerform() {
// this crashes with 2 iterations or more with a EXC_BAD_ACCESS
DispatchQueue.concurrentPerform(iterations: 2, execute: { _ in
wasteMemory()
})
}
func testWasteWithEnumerateObjects() {
// this crashes with 17 iterations or more with a EXC_BAD_ACCESS
(Array(1...17) as NSArray).enumerateObjects(options: [.concurrent]) { _, _, _ in
wasteMemory()
}
}
}
Post not yet marked as solved
I was noticing that my NSWindowControllers were never being deallocated when windows were closed, and I narrowed it down to an issue where an NSWindow seems to have a strong reference to its delegate, despite theclass SimpleWindow : NSWindow, NSWindowDelegate { /// Debug variable to see how many instances are around public private(set) static var InstanceCount = 0 deinit { SimpleWindow.InstanceCount -= 1 } override init(contentRect: NSRect, styleMask style: NSWindow.StyleMask, backing backingStoreType: NSWindow.BackingStoreType, defer flag: Bool) { super.init(contentRect: contentRect, styleMask: style, backing: backingStoreType, defer: flag) SimpleWindow.InstanceCount += 1 }}class WindowReferenceTests: XCTestCase { func testWindows() { let startCount = SimpleWindow.InstanceCount do { let wc = SimpleWindow() wc.delegate = wc // weak open var delegate: NSWindowDelegate? XCTAssertEqual(startCount + 1, SimpleWindow.InstanceCount) } XCTAssertEqual(startCount, SimpleWindow.InstanceCount, "window controllers have circular references somewhere") }}
My app uses the vibrantDark appearance, but when I add an NSPredicateEditor as a subview, its predicate rows draw with an aqua background color. But the sub-controls (popups and text fields) are drawn using the hierarchy's vibrantDark appearance, which makes the editor unusable. Is this a known issue? And is there any workaround?
Post not yet marked as solved
I have a Formatter that handles value types. For the purposes of this example, let's say it is a Bool formatter:@objc final class BoolFormatter : Formatter {
override func string(for obj: Any?) -> String? {
return (obj as? Bool) == true ? "true" : "false"
}
}It works fine. But now I want to be able to parse the Bool:@objc final class BoolFormatter : Formatter {
override func string(for obj: Any?) -> String? {
return (obj as? Bool) == true ? "true" : "false"
}
override func getObjectValue(_ obj: AutoreleasingUnsafeMutablePointer<AnyObject?>?, for string: String, errorDescription error: AutoreleasingUnsafeMutablePointer<NSString?>?) -> Bool {
if string == "true" {
obj?.pointee = true
return true
} else if string == "false" {
obj?.pointee = false
return true
} else {
if let error = error {
error.pointee = "String was not a boolean"
}
return false
}
}
}This fails, because Bool is not an AnyObject. Is there some special reason why Formatter can format Any (value or class), but requires AnyObject for parsing? It seems wasteful to have to wrap the value in a NSNumber or some other class.