Mr. Smith
Mr. Smith

Reputation: 4516

Objective C Private Public Methods In Same Category

What I'd like to do is separate a category's methods into private and public methods. The private methods need to be visible outside of that category's file, but not outside the class.

For instance, let's say I have the following files:

ClassA.m
ClassA.h // <-- Includes definitions of public category methods
ClassAPrivates.h // <-- Includes definition of private category methods.
ClassA+Render.m

ClassAPrivates.h would look like this:

@interface ClassA()
// private methods here, for use inside ClassA
@end
@interface ClassA(Render)
// the private methods of the Render category.
-(void)privateConfigureDeviceContext;
-(void)privateConfigureBufferSpace;
@end

And 'ClassA.h' would look like this:

@interface ClassA : NSObject
// public methods of ClassA
@end
@interface ClassA (Render)
// public methods of category Render
-(void)drawLine;
-(void)drawCircle;
@end

However, XCode complains about duplicate interface for Render. Any workarounds?

Upvotes: 0

Views: 421

Answers (4)

user1046037
user1046037

Reputation: 17725

No need to create separate categories for private methods.

There are 3 scenarios:

  1. ClassA+Render.m accessing the private methods that are defined in the ClassA.m
  2. ClassA.m accessing the private methods that are defined in ClassA+Render.m
  3. ClassA+Render.m accessing the properties defined in ClassA.m

Note: Though the original poster hasn't asked for Scenario 3, I thought it might come in handy

Example

ClassA.m defines 2 private methods

  • basePrivateMethod1 - This would invoke renderPrivateMethod1
  • basePrivateMethod2

ClassA+Render.m defines 2 private methods

  • renderPrivateMethod1
  • renderPrivateMethod2 - This would invoke basePrivateMethod2

Scenario 1

  • In ClassA+Render.m just create an extension and forward declare the methods that you want to use.

ClassA+Render.m

@interface ClassA ()

- (void) basePrivateMethod1; //Just forward declare the method

@end

Scenario 2

  • In ClassA+Render.h just declare the methods defined in ClassA+Render.m.
  • In ClassA.m just include (#import) ClassA+Render.h
  • Pls note, ClassA+Render.h would / should not be used outside of ClassA

ClassA+Render.h

@interface ClassA (Render)
{
    - (void) basePrivateMethod2;
}

Scenario 3

  • Pls note - Properties can not be defined / created in the categories
  • So create a new category called ClassA+Properties
  • In ClassA+Properties.h redeclare all the properties
  • In ClassA+Properties.m use @dynamic for all the properties to tell the compiler that the actual definition of these properties is else where
  • In ClassA+Render.m include (#import) ClassA+Properties.h, so that all the properties are accessible

ClassA+Properties.h

@interface ClassA (Properties)
{
    @property NSUInteger property1;
    @property NSUInteger property2;
}

ClassA+Properties.m

@interface ClassA (Properties)
{
    @dynamic property1;
    @dynamic property2;
}

Upvotes: 1

adib
adib

Reputation: 8395

You can declare Render's private methods in a class extension in its own file. This takes advantage that you can have multiple class extensions.

ClassA.h:

@interface ClassA : NSObject
// public methods of ClassA
@end

ClassA+Render.h:

@interface ClassA (Render)
// public methods of category Render
-(void)drawLine;
-(void)drawCircle;
@end

ClassA+Render_Private.h:

@interface ClassA ()
// the private methods of the Render category.
-(void)privateConfigureDeviceContext;
-(void)privateConfigureBufferSpace;
@end

Upvotes: 0

Anoop Vaidya
Anoop Vaidya

Reputation: 46563

Category is a concept which states any new method can be added to an existing class and all subclass will eventually get that method.

You use categories to define additional methods of an existing class—even one whose source code is unavailable to you—without subclassing. You typically use a category to add methods to an existing class, such as one defined in the Cocoa frameworks. The added methods are inherited by subclasses and are indistinguishable at runtime from the original methods of the class.

If you are adding private method, then why to go with category? As it can be used only by that single class file itself. Therefore why not to create a normal private method!!!

Upvotes: 0

FluffulousChimp
FluffulousChimp

Reputation: 9185

You declare two categories named Render on ClassA. That is why Xcode is complaining.

Upvotes: 0

Related Questions