What does the @package directive do in Objective-C?

Does anyone know exactly what the @package directive is used for in Objective-C?

The only mention I could find of it in Programming in Objective-C 2.0 by Stephen Kochan was:

@package - For 64 bit images, the instance variable can be accessed anywhere within the image that implements the class

...

What? Is this restricted to being used with images, as in pictures? Or does it mean images as in disk images?

It's a confusing description, and doesn't elaborate whatsoever throughout the rest of the book....

Any help would be awesome, thanks!


Solution 1:

@package is similar to internal for .NET. It means the member is accessible only from the framework in which it is defined.

Note: In 32-bit it acts like @public.

Solution 2:

Apple's documentation explains this a bit, but here's a bit more detail…

Instance variables that are declared under @package will only be accessible by code from the same framework, library or executable. This is most similar to internal in C# and Friend in VB.NET, but other programming languages have similar protections schemes as well (Java has package-private).

For instance, imagine a framework, RecipeKit.framework, for managing recipes:

@interface Recipe : NSObject {
  @package;
    NSString *name;
  @private;
    NSArray *ingredients;
}
@end

@interface RecipeController : NSObject
@end

The recipe controller will be able to access the names of recipes directly. You would be able to write something like this in the RecipeController since it's part of the same framework:

Recipe *recipe = [[[Recipe alloc] init] autorelease];
[recipe->name autorelease];
recipe->name = [@"The best ever recipe!" retain];

If you were to write the above code in an application linking to RecipeKit, though, it would cause a compiler error since you don't have access to that variable. Lastly, when compiled for 32-bit, variables declared under @package behave as if they were declared under @public instead, so watch out for the differences here.

This new feature got very little attention because it's just one more way of breaking you're class's encapsulation. As has always been true, you're probably better off working with @private variables only and having accessor methods for them. In fact, for a while Apple was trying to push this by including @private in their templates. With properties in Objective-C 2.0, sticking with @private is easy enough, and depending on what platform you're targeting, you can leave out the instances variables entirely.


Images

One thing that a few of the previous answers left a little unclear was addressing the aspect of images from the original question. In fact, the word image as used in the description of @package variables has nothing to do with graphical images. Instead it is referring to images that the dynamic linker is able to load. Generally executables, frameworks, and dynamic libraries are all considered images by the linker (though they are handled slightly differently). You'll see the word image pop up every once and a while. For instance, a common runtime error is: "dyld image not found". You'll also find the use of the word image scattered throughout documentation for dyld. Reading through the man page for dyld could help clear up the ambiguity of this word a bit. UIImage may declare variables as @package, but it has nothing to do with image as it pertains to the original question.