3

I've created a singleton object in Swift 4.2 and am attempting to access it (call a couple methods) in an Objective-C class. However, when calling the instance in Objective-C, the app crashes with the following:

EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

enter image description here

My Swift singleton definition isn't anything unusual, and it works fine when called only from other Swift classes. Here's what it looks like:

@objc public static let sharedManager = SessionManager()

It doesn't seem to be an issue with language interoperability in the project either: non-singleton files don't cause a crash when accessed from Objective-C. I'm also not sure that this Objective-C code is so wild that it should be causing it either:

// Have attempted both flavors here, the crash is coming from the call to "sharedManager", which the runtime thinks is nil
SessionManager *manager = [SessionManager sharedManager];
[manager setSession:nil];

Any ideas on how to fix this? What am I missing? Why would the singleton instance ever be nil?


Edit: I've attempted expanding the implementation of the Swift Singleton to this, and its still not working:

@objc final class SessionManager: NSObject {
    @objc public static let _sharedManager = SessionManager()
        private override init() {
        super.init()
    }

    @objc public class func sharedManager() -> SessionManager {
        return SessionManager._sharedManager
    }
}
Sam Spencer
  • 8,492
  • 12
  • 76
  • 133
  • What methods are you calling from within objective-c? You might be doing some swifty stuff in there that doesn't necessarily translate well to the objc runtime memory wise. – Antwan van Houdt Jan 09 '19 at 21:59
  • Show us full singleton code. – GeneCode Jan 10 '19 at 00:21
  • @GeneCode As of Swift 4, as per Apple documentation, that is the full & recommended way to create a singleton. One line. Seems like there should be more though, because obviously its an issue. – Sam Spencer Jan 10 '19 at 01:06
  • @AntwanvanHoudt I've edited the question with a more detail on the ObjC side of things. Unfortunately it looks like "sharedManager" is nil when it gets accessed from ObjC. – Sam Spencer Jan 10 '19 at 01:09
  • Hmm.. not seeing the class portion of the singleton?? See here: https://stackoverflow.com/a/26743597/501439 – GeneCode Jan 10 '19 at 01:20
  • @GeneCode Thanks for the link -- I feel like I've tried every variation of this (see edit above). – Sam Spencer Jan 10 '19 at 22:24

1 Answers1

2

When accessing a Singleton in Objective-C for the first time, each variable stored in the class must be initialized.

I found that what was happening (and what made this so frustrating) was that one of the objects being initialized made calls back to the singleton object in its own initializer -- thus forming an infinite loop that the runtime couldn't exit.


If you're coming here from Google... when creating a Singleton object with non-optional variables, make sure that the initializers for the variables make no references to the singleton from which they are being initialized. Basically, avoid inadvertently creating infinite loops.

UPDATE: A bug report radar has been filed with the Swift team.

Sam Spencer
  • 8,492
  • 12
  • 76
  • 133