3

I am in the process of creating a category for the class MKPolygon. You can find the reference to this class here. I have two public class methods that I want to make "public" and a handful of "private" methods to handle some of the internals. The reason I want to do this is because, as you can see, the methods available for this class are class methods and I want to continue with being in line with this by offering class methods which will both be returning (MKPolygon *). Also, there will be a lot of work that I will be writing and not breaking up the tasks would go against good coding practices and of course hard to test and read - this is especially important as I will be contributing this to github.

Here is my header and implementation file that was created when creating a new category in XCode. I am going to make the methods generic for now to get my point across:

MKPolygon+MKPolygonStuff.h

#import <MapKit/MapKit.h>

@interface MKPolygon (MKPolygonStuff){

}
+(MKPolygon *)polygon:(MKPolygon *)poly1 doStuff:(MKPolygon *)poly2 onMap:(MKMapView *)map;
+(BOOL)polygon:(MKPolygon *)poly1 doesThisThing:(MKPolygon *)poly2;

@end

MKPolygon+MKPolygonStuff.m

@interface MKPolygon(){


}

+(void)calculateStuff;

@end

@implementation MKPolygon (MKPolygonStuff)

+(void)calculateStuff{



}
+(MKPolygon *)polygon:(MKPolygon *)poly1 doStuff:(MKPolygon *)poly2 onMap:(MKMapView *)map{

  //do stuff and call other class methods to break up tasks
  //[self calculateStuff];

 }

+(BOOL)polygon:(MKPolygon *)poly1 doesThisThing:(MKPolygon *)poly2{

    //returns boolean
    //possibly call other class methods do some internals.
}

In my implmentation file my interface had something within the parenthesis but it gave me the following warning:

"Duplicate definition of category on interface..."

So i decided that i would just leave the parenthesis empty after reading a couple of other threads in here regarding this issue. Also doing this would allow me to have instance variables that I will most definitely need that I dont want to be made "public".

Now I have a warning that is located under the implementation section next to +(void)calculateStuff.

"Category is implementing a method which will also be implemented by its primary class".

I searched this warning around the net to see what would cause this warning and it seems that you would get this warning if the compiler recognizes that you will be overriding some built in functionality to the class. The thing is, is that there isn't a calculateStuff method in the MKPolygon class, so I am unsure why i am getting this warning. Is there something here that I am doing wrong, if anything and generally, do I have everything set up right here with that I want to do? Obviously, my private methods have to be class methods as well since you can't call instance methods from class methods.

Would appreciate any comments/suggestions/corrections here.

cspam
  • 2,911
  • 2
  • 23
  • 41

1 Answers1

1

If calculateStuff is a private method that is only used in the implementation block of the MKPolygon (MKPolygonStuff) category then you need not declare that method in an interface at all.

Just remove @interface MKPolygon() ... @end from "MKPolygon+MKPolygonStuff.m".

With current Xcode/clang versions, you even need not forward declare a method that is defined and used inside an implementation block.

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • but I am going to need "private" objects to manage all of the work that I will be doing within the class methods... so as an example I know that I am going to need two NSMutableArray objects, maybe others. in this case I will need to keep the @interface...@end block. Overall does everything else looks like it is set up ok? This is my first time working with Categories. thanks. – cspam Jun 02 '13 at 21:14
  • @cspam: Your question was about a (private) *method* in a category, and it should compile if you remove the part as suggested in my answer. - But *you can't add instance variables in a category!!!* The only workaround for that is to use "associated objects". See e.g. http://stackoverflow.com/questions/13000693/how-to-add-a-variable-to-category-in-objective-c for more information (but it is not trivial). – Martin R Jun 02 '13 at 21:21
  • it was interesting, when i put something in the parenthesis in the interface, and tried to add something like NSMutableArray *poly1 it gave me a compiler error that i couldnt add instance variables. If i leave the parenthesis empty..I get no such error. however, of course when trying to instantiate the array it gives me a compiler error, "instance variable accessed in class method". Just interesting how the compiler works here. Thanks for the link. Will look at that. thanks again – cspam Jun 02 '13 at 21:25
  • oh yeah, i accepted. :) the other thing that i can do is define and instantiate local objects within my class methods and just pass the pointers to these objects back and forth via the other class methods as needed. – cspam Jun 02 '13 at 21:34
  • @cspam: One final remark: With empty parentheses `@interface MKPolygon()` you have a "class extension", not a "category". You can add instance variables in a class extension, but these can be used only in the implementation block of the class (`MKPolygon` in this case), so that does not help. – Martin R Jun 02 '13 at 21:35