+bundleForClass: category question

  • If I create a category on a standard framework class as part of another framework, and I use +[NSBundle bundleForClass:] to load an image resource for use by that category, does that work, i.e. does it load the bundle of the framework containing the category, or the bundle containing the original class being extended?

    --Graham
  • On Jul 15, 2012, at 7:30 PM, Graham Cox <graham.cox...> wrote:

    > If I create a category on a standard framework class as part of another framework, and I use +[NSBundle bundleForClass:] to load an image resource for use by that category, does that work, i.e. does it load the bundle of the framework containing the category, or the bundle containing the original class being extended?

    The category is a method on the class you specify, therefore [self class] will be that class (whatever it is) and you will get the bundle for that class. In this case, it means your bundle will be the framework bundle.
    --
    David Duncan
  • On 16/07/2012, at 1:29 PM, David Duncan wrote:

    > In this case, it means your bundle will be the framework bundle.

    Just to be clear, you mean the bundle for the *original* framework (AppKit, say) and not my framework which contains the category?

    --Graham
  • On Jul 15, 2012, at 9:07 PM, Graham Cox <graham.cox...> wrote:

    >
    > On 16/07/2012, at 1:29 PM, David Duncan wrote:
    >
    >> In this case, it means your bundle will be the framework bundle.
    >
    > Just to be clear, you mean the bundle for the *original* framework (AppKit, say) and not my framework which contains the category?

    Yup.
    --
    David Duncan
  • On Jul 15, 2012, at 8:29 PM, David Duncan <david.duncan...> wrote:

    > The category is a method on the class you specify, therefore [self class] will be that class (whatever it is) and you will get the bundle for that class. In this case, it means your bundle will be the framework bundle.

    That's an ambiguous answer since Graham's got his own framework too.

    The answer, I think, is the _system_ framework bundle that contains the base implementation of the class, not Graham's framework with the category.

    —Jens
  • The answer is simple, and it's answered by the name of the method:

    -bundleForClass:

    Graham's framework does not define the class.  Therefore, it is not the bundle that is returned from the method.  This method returns the bundle that defines the class.  In Graham's example, it would be the system framework.

    Dave

    On Jul 16, 2012, at 2:08 PM, Jens Alfke wrote:

    >
    > On Jul 15, 2012, at 8:29 PM, David Duncan <david.duncan...> wrote:
    >
    >> The category is a method on the class you specify, therefore [self class] will be that class (whatever it is) and you will get the bundle for that class. In this case, it means your bundle will be the framework bundle.
    >
    > That's an ambiguous answer since Graham's got his own framework too.
    >
    > The answer, I think, is the _system_ framework bundle that contains the base implementation of the class, not Graham's framework with the category.
    >
    > —Jens
  • On 17/07/2012, at 7:15 AM, Dave DeLong wrote:

    > The answer is simple, and it's answered by the name of the method:
    >
    > -bundleForClass:
    >
    > Graham's framework does not define the class.  Therefore, it is not the bundle that is returned from the method.  This method returns the bundle that defines the class.  In Graham's example, it would be the system framework.

    That was my assumption, so the answer was what I expected. But I also wondered whether it was possibly a bit smarter and used the full category name as the class name.

    What I'm trying to do is to add a couple of cursors to NSCursor using a category which are created by loading images from the framework's resources. Unfortunately it doesn't work when implemented in a simple way because +bundleForClass returns the bundle containing NSCursor. Instead I have to declare an intermediate class that loads the image resource for me - I was just hoping to avoid that extra step but seems not.

    --Graham
  • On Tue, Jul 17, 2012, at 11:02 AM, Graham Cox wrote:
    >
    > What I'm trying to do is to add a couple of cursors to NSCursor using a
    > category which are created by loading images from the framework's
    > resources. Unfortunately it doesn't work when implemented in a simple way
    > because +bundleForClass returns the bundle containing NSCursor. Instead I
    > have to declare an intermediate class that loads the image resource for
    > me - I was just hoping to avoid that extra step but seems not.

    Since the identifier of the bundle is known at compile time, we have a
    compile-time define that we use whenever we need to provide an NSBundle
    in a situation like this:
    https://github.com/omnigroup/OmniGroup/blob/master/Frameworks/OmniBase/OBUt
    ilities.h#L64


    Basically, we define OMNI_BUNDLE_IDENTIFIER in the Xcode project, use
    the "Preprocess Info.plist" option to insert it into the
    CFBundleIdentifier property, and use OMNI_BUNDLE whenever we need to
    provide a "this-bundle"-relative NSBundle argument. OMNI_BUNDLE
    essentially expands to [NSBundle bundleWithIdentifier:OMNI_BUNDLE].

    --Kyle Sluder
  • On Jul 16, 2012, at 6:02 PM, Graham Cox <graham.cox...> wrote:

    > What I'm trying to do is to add a couple of cursors to NSCursor using a category which are created by loading images from the framework's resources. Unfortunately it doesn't work when implemented in a simple way because +bundleForClass returns the bundle containing NSCursor. Instead I have to declare an intermediate class that loads the image resource for me - I was just hoping to avoid that extra step but seems not.

    Why not just make a subclass of NSCursor and put the accessor methods on that? It's safer than a category since you don't run the risk of colliding with a method name added by another framework/bundle in the same process, or by a future version of NSCursor itself.

    —Jens
  • On 16.07.2012, at 04:30, Graham Cox wrote:
    > If I create a category on a standard framework class as part of another framework, and I use +[NSBundle bundleForClass:] to load an image resource for use by that category, does that work, i.e. does it load the bundle of the framework containing the category, or the bundle containing the original class being extended?

    You'll always get the bundle where the class was originally defined, not your category's. A workaround that I occasionally do in categories is that I define a dummy "anchor" class next to the category and call -bundleForClass: on that. Very useful for code that is used on iOS (there are no frameworks) and on the Mac (in a framework). It'll always grab the bundle to which someone added that source file, and the assumption is whoever did that also copied along the resources.

    -- Uli Kusterer
    "The Witnesses of TeachText are everywhere..."
    http://www.masters-of-the-void.com
previous month july 2012 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today