title: Can you create class methods in Objective-C only visible within your library?
body: <p>I found <a href="https://stackoverflow.com/questions/6006701/friend-class-in-objective-c">this StackOverflow question on friend classes in Objective-C</a> which was <strong><em>similar</em></strong> to the issue I'm trying to solve, but not quite the same. So I'd like to extend their example.</p>
  
  <p>Suppose I want the ability to hand a Monkey multiple Bananas and he'll keep an array of all of his own Bananas. When I tell him to eat, he eats from his array. I can then ask him to give me a Banana at random:</p>
  
  <p><strong>Banana.h</strong></p>
  
  <pre><code>@interface Banana : NSObject
  - (BOOL)isPeeled;
  @end
  </code></pre>
  
  <p><strong>Banana.m</strong></p>
  
  <pre><code>#import "Banana.h"
  
  @implementation Banana
  {
      @private
      BOOL peeled;
  }
  
  - (id)init
  {
      self = [super init];
      if (self)
      {
          peeled = NO;
      }
      return self;
  }
  
  - (void)peel // PRIVATE METHOD
  {
      peeled = YES;
  }
  
  - (BOOL)isPeeled
  {
      return peeled;
  }
  @end
  </code></pre>
  
  <p><strong>Monkey.h</strong></p>
  
  <pre><code>#import "Banana.h"
  
  @interface Monkey : NSObject
  - (void)give:(Banana *)aBanana;
  - (void)eat;
  - (Banana *)getBanana;
  @end
  </code></pre>
  
  <p><strong>Monkey.m</strong></p>
  
  <pre><code>#import "Monkey.h"
  
  @implementation Monkey
  {
      @private
      NSMutableArray *bananas;
  }
  
  - (id)init
  {
      self = [super init];
      if (self)
      {
          bananas = [[NSMutableArray alloc] init];
      }
      return self;
  }
  
  - (void)give:(Banana *)aBanana
  {
      [bananas addObject:aBanana];
  }
  
  - (void)eat
  {
      BOOL hungry = YES;
      for (int i = 0; i &lt; bananas.count; i++)
      {
          if (!banana.isPeeled)
          {
              hungry = NO;
              [banana peel];
              break;
          }
      }
      if (hungry)
      {
          NSLog(@"Monkey ANGRY!");
      }
  }
  
  - (Banana *)getBanana
  {
      int r = arc4random_uniform(bananas.count);
      return [bananas objectAtIndex:r];
  }
  @end
  </code></pre>
  
  <p>In this case, <code>Banana.h</code> and <code>Monkey.h</code> would be public headers in a library I'm distributing. The intended use of my library would look something like so:</p>
  
  <p><strong>ClientApp.m</strong></p>
  
  <pre><code>#import "MonkeyLib/MonkeyLib.h"
  
  @implementation SomeClass
  
  - (void)someMethod
  {
      Banana *oneBanana = [[Banana alloc] init];
      Monkey *oneMonkey = [[Monkey alloc] init];
      [oneMonkey give:oneBanana];
      [oneMonkey eat];
      Banana *twoBanana = [oneMonkey getBanana];
      if (twoBanana.isPeeled)
      {
          NSLog(@"No sad monkeys!");
      }
  }
  
  @end
  </code></pre>
  
  <p>The immediate issue with the code above is that my library won't compile because no interface for the class <code>Banana</code> defines a <code>peel</code> method (as utilized by <code>Monkey.m</code>)</p>
  
  <p>The StackOverflow question I linked at the beginning of this question suggests creating a third header file:</p>
  
  <p><strong>BananaPrivate.h</strong></p>
  
  <pre><code>@interface Banana (PrivateMethods)
  - (void)peel;
  @end
  </code></pre>
  
  <p>Then in <code>Monkey.m</code> I can import <code>BananaPrivate.h</code> and I can suddenly call the <code>peel</code> method. However this fails because when I attempt to import <code>BananaPrivate.h</code> I create a collision -- I've already defined <code>Banana</code> when I imported <code>Banana.h</code> in <code>Monkey.h</code></p>
  
  <p>I can't remove <code>Banana.h</code> from <code>Monkey.h</code>, because one of the methods on <code>Monkey</code> returns an instance of type <code>Banana</code>!</p>
  
  <p>I found a quirky work-around by sub-classing <code>Banana</code> like so:</p>
  
  <p><strong>InternalBanana.h</strong></p>
  
  <pre><code>@interface InternalBanana : Banana
  - (void)peel;
  @end
  </code></pre>
  
  <p>Then within <code>Monkey.m</code> I can safely <code>#import "InternalBanana.h"</code>. However this has two issues:</p>
  
  <ol>
  <li>It only works for Bananas instantiated <strong>by my Monkey</strong> (if a user of my library instantiates a Banana and passes it to my Monkey, it will be a Banana and not an InternalBanana)</li>
  <li>I have to create an <code>InternalBanana.m</code> file, but within this file I <strong>cannot</strong> define <code>peel</code>. Attempting to define <code>peel</code> within <code>InternalBanana.m</code> will throw an error that <code>peeled</code> is not defined, since <code>peeled</code> is a private variable of the super class. If I define <code>peel</code> within <code>InternalBanana.m</code> and it only calls <code>[super peel]</code>, that will also fail since <code>Banana</code> does not define a <code>peel</code> method. While this <strong><em>works</em></strong>, it does cause Xcode to throw a warning saying that there is no method definition for <code>peel</code> (but it builds and runs despite the warning)</li>
  </ol>
  
  <p>What is the <strong><em>proper</em></strong> solution to this monkey business?</p>