Reputation: 4516
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
Reputation: 17725
No need to create separate categories for private methods.
There are 3 scenarios:
ClassA+Render.m
accessing the private methods that are defined in the ClassA.m
ClassA.m
accessing the private methods that are defined in ClassA+Render.m
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
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
ClassA+Render.h
just declare the methods defined in ClassA+Render.m
.ClassA.m
just include (#import
) ClassA+Render.h
ClassA+Render.h
would / should not be used outside of ClassA
ClassA+Render.h
@interface ClassA (Render)
{
- (void) basePrivateMethod2;
}
Scenario 3
ClassA+Properties
ClassA+Properties.h
redeclare all the properties ClassA+Properties.m
use @dynamic
for all the properties to tell the compiler that the actual definition of these properties is else whereClassA+Render.m
include (#import
) ClassA+Properties.h
, so that all the properties are accessibleClassA+Properties.h
@interface ClassA (Properties)
{
@property NSUInteger property1;
@property NSUInteger property2;
}
ClassA+Properties.m
@interface ClassA (Properties)
{
@dynamic property1;
@dynamic property2;
}
Upvotes: 1
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
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
Reputation: 9185
You declare two categories named Render
on ClassA
. That is why Xcode is complaining.
Upvotes: 0