The main thread isn’t deallocating the PointerTest object, because it’s saved in the AppDelegate.
Rob > On Jun 18, 2017, at 10:45 AM, Michel Fortin <michel.for...@michelf.ca> wrote: > > The problem is that the main thread is deallocating the object before the > other thread has a chance to see it. Ideally you'd pass a managed object > reference to the block that runs in the other thread so the reference count > does not fall to zero. If you absolutely need to pass it as an unsafe pointer > then you must manage the reference count manually, like this: > > let unsafePtr = Unmanaged.passRetained(self).toOpaque() > let safe = > Unmanaged<PointerTest>.fromOpaque(unsafePtr).takeRetainedValue() > useSafeObject(safe) > > Make sure the calls to passRetained and takeRetainedValue are balanced. (If > this is a callback that gets called multiple times, use takeRetainedValue > only once at the end.) > >> Le 18 juin 2017 à 9:23, Robert Nikander via swift-users >> <swift-users@swift.org <mailto:swift-users@swift.org>> a écrit : >> >> Hi, >> >> I’m porting some C to Swift and I need to pass a Swift instance through a >> `void *` (ie, UnsafeMutableRawPointer). It works, in one thread, but when a >> second thread accesses the exact same pointer, it fails with memory errors >> like EXC_BAD_ACCESS >> >> The code below could be pasted into an AppDelegate.swift in a new single >> view iOS project. >> >> Anyone know what’s going on here? The second call to >> `tryUsingUnsafePointer`, in the new thread, crashes. >> >> Rob >> >> >> class PointerTest { >> >> let str = "Hello" >> >> init() { print("PointerTest.init") } >> deinit { print("PointerTest.deinit") } >> >> func start() { >> var mSelf = self >> let unsafePtr = UnsafeMutableRawPointer(&mSelf) >> tryUsingUnsafePointer(unsafePtr) >> print("Passing unsafe pointer to another thread: \(unsafePtr)") >> >> Thread.detachNewThread { >> tryUsingUnsafePointer(unsafePtr) >> } >> } >> } >> >> func tryUsingUnsafePointer(_ ptr: UnsafeMutableRawPointer) { >> print("Using unsafe pointer:") >> let typedPtr = ptr.assumingMemoryBound(to: PointerTest.self) >> // let typedPtr = ptr.bindMemory(to: PointerTest.self, capacity: 1) >> print(" typedPtr: \(typedPtr)") >> let obj = typedPtr.pointee >> print(" obj.str: \(obj.str)") // Memory error happening here, or >> sometimes line above >> } >> >> >> @UIApplicationMain >> class AppDelegate: UIResponder, UIApplicationDelegate { >> >> var window: UIWindow? >> var ptrTest: PointerTest? >> >> func application(_ application: UIApplication, >> didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: >> Any]?) -> Bool { >> >> ptrTest = PointerTest() >> ptrTest?.start() >> >> return true >> } >> >> [...] >> >> >> >> >> _______________________________________________ >> swift-users mailing list >> swift-users@swift.org <mailto:swift-users@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-users > > -- > Michel Fortin > https://michelf.ca <https://michelf.ca/>
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users