Proper way for classes to announce their existence

Discussion in 'Mac Programming' started by Qaanol, Sep 4, 2013.

  1. macrumors 6502a

    Joined:
    Jun 21, 2010
    #1
    I am writing a simulation program, which will present the user with a list of available simulators to run. Each simulator is implemented as a class, and I want to know the correct way for the program to keep track of the available simulator classes. Ideally the solution should be robust in the case of dynamically-loaded classes.

    My first thought is to have a SimulatorManager class which exists as a singleton instance that keeps an NSArray of simulator classes, and have each simulator class implement +load to call [[SimulatorManager sharedInstance] registerSimulator:self]. However, I am not sure if this is the right way to do it, nor if it is even possible to rely on an instance of one class during +load of another.

    How should I go about keeping a list of simulator classes known to the application?
     
  2. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #2
    Google for "Objective C Runtime", then look for "objc_getClassList" and go from there.
     
  3. thread starter macrumors 6502a

    Joined:
    Jun 21, 2010
    #3
    I can say for sure that I definitely do not want to parse the entire list of classes known to the runtime to populate the list. For starters, it means I would have to parse the list of all classes every time I wanted to check whether the list might possibly need to be updated, which is absurd.

    I definitely want the classes to announce their existence in a defined manner, and I am asking for the proper way to implement that.
     
  4. macrumors G5

    gnasher729

    Joined:
    Nov 25, 2005
    #4
    They all do announce their existence, and the Objective C runtime puts them into the list of all classes. What do you think does the runtime do when you ask for a class by name?
     
  5. macrumors 603

    Joined:
    Aug 9, 2009
    #5
    Dynamic loading under Cocoa is done using bundles.
    https://developer.apple.com/library...ceptual/LoadingCode/Tasks/LoadingBundles.html

    Look at the left-hand column in that article. See the "Multi-Bundle Applications" and "Plug-in Architectures" in particular. Also see the Related Documents list.

    Found using google search terms:
    cocoa bundle loading
    which produces some other results that may be useful.
     
  6. thread starter macrumors 6502a

    Joined:
    Jun 21, 2010
    #6
    Yes I am familiar with Cocoa bundles and had a plug-in architecture in mind when I posted this thread. One way for my application to determine what classes are available in a plug-in is for the principal class of the bundle to keep a hard-coded list of the available classes.

    I prefer to avoid a hard-coded solution if I can help it. I would much prefer to have each class announce itself to my code when it is loaded. Is there a viable way to accomplish that result?
     
  7. macrumors 603

    Joined:
    Aug 9, 2009
    #7
    See the class methods +load and +initialize.

    Also see: Dynamic Loading.

    Google search terms: cocoa class loading


    Regardless of the mechanism you use, I suspect you'll need to do a fair amount of testing, trials, and plain old discovery. I strongly doubt you'll find a ready-made or simple solution that does everything you want.
     
  8. thread starter macrumors 6502a

    Joined:
    Jun 21, 2010
    #8
    Indeed, I believe I specifically mentioned +load in my original post, and asked whether the approach I had in mind using that function was the right way to go.

    Perhaps, but I think it is quite likely I may find someone with experience doing the same thing, hence why I posted here.
     
  9. macrumors 603

    Joined:
    Aug 9, 2009
    #9
    Whether it's right or not will depend on several things. Inter-class dependencies, for one thing. That's one reason I pointed to bundles, because those are well-defined loadable modules, and finding examples shouldn't be difficult.

    The top google result for cocoa class loading is this, which discusses +load, +initialize, etc.
    http://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html

    Farther down but still on the first page of results:
    http://www.cocoawithlove.com/2010/01/getting-subclasses-of-objective-c-class.html

    Google has additional results worth looking at. That's why I post the search terms.
     
  10. thread starter macrumors 6502a

    Joined:
    Jun 21, 2010
    #10
    All right, both of those links discuss using +load essentially as I described (although they use factory class methods rather than a singleton instance). Notably though, they both specifically register subclasses with a superclass.

    I infer this means it is definitely acceptable for subclasses to register themselves with a superclass. The NSObject documentation mentions that +load is guaranteed to be called for a superclass before any of its subclasses, which seems potentially relevant.

    Do we know if it is okay for classes to use +load to register themselves with a class which they do not inherit from?
     
  11. macrumors 603

    Joined:
    Aug 9, 2009
    #11
    The main constraint that comes to mind is whether the class they wish to register with has itself been +load'ed and +initialize'd. If I had to be certain, I would use plain C (e.g. a linked list, perhaps encapsulated in a function) and sidestep the question of class-load order.

    Or write some trial code and see what happens.
     
  12. thread starter macrumors 6502a

    Joined:
    Jun 21, 2010
    #12
    Hmm, the NSObject documentation for +load mentions, "In a custom implementation of load you can therefore safely message other unrelated classes from the same image, but any load methods implemented by those classes may not have run yet."

    With that, and given that framework classes are guaranteed to have already been loaded and initialized, I suspect that having [SimulatorManager registerSimulator:self] curate a static NSArray might work. I do not need SimulatorManager to implement a +load method, so it does not matter to me if it has been called prior to +registerSimulator:(id)sender.

    I certainly will, I just wanted to check here because I expect that +load is exactly the sort of place that subtle things could happen sometimes but not others, and I might not notice if things didn't act up at first.
     

Share This Page