tags:

views:

122

answers:

3

I have two methods -a and -b. -a calls sometimes -b, and -b sometimes calls -a. Both methods are intended to be private, and not called from outside.

But I had to make one of them public in the .h file, because otherwise the compiler would go crazy and give a warning for either one of them.

Is there any valid and good-practise solution for that problem?

+1  A: 

Implement a protocol.

or

Write a second header file with a category.

Georg
A second file would be pretty hard to maintain, I think ;) but might be a solution too. Like the "inside category" more.
Thanks
+6  A: 

Traditionally, what you'd do is define a category (something like @interface MyClass (MyClass_Private) inside the implementation file that declares the private methods. Apple recently introduced a feature called a class extension that is intended for this exact case. It's basically a specialization of a category, but the class has to implement the methods when it's first defined. It looks like:

@interface MyObject ()
    - (void)setNumber:(NSNumber *)newNumber;
@end
Chuck
Great! That works very good. One think though: What's that () good for after "MyObject"? I replaced "MyObject" with the name of my class that needs the private method. When I remove the () brackets, then I get an error that there's aready a class named so. I left them there ;) ...works! Thanks!
Thanks
The () is what marks it as a class extension. It's basically the same thing as the () in a category declaration, except class extensions aren't named.
Chuck
In other words, without the parentheses, you just have @interface MyClass, which is the declaration of a class (rather than an extension or category). Since you've already declared that class, the compiler will complain.
Chuck
I always thought a catagory is a class extension, since it extends a class ;) where's the difference?
Thanks
Per "The Objective-C Programming Language": Class extensions are like “anonymous” categories, except that the methods they declare must be implemented in the main @implementation block for the corresponding class.
Chuck
+1  A: 

If you really want the functions to be private, you need to declare them as static. To eliminate the cyclic dependency, one should be declared before the other is defined. Here's a simple example:

static void b(); /* forward declaration */

static void a()
{
    if (foo)
        b(); /* forward-declared, so we're ok */
}

static void b()
{
    if (bar)
        a(); /* already defined, so we're ok */
}

This is all valid C, and so based on the OP's comment I assume this is valid ObjC as well.

Tom
Interesting. But a.f.a.i.k. an static method has no access to the instance variables of an object, right? At least, that's in Java the case (which makes sense).
Thanks
Ah... yeah, I read "method" as function, due to my background (and the context of the question). If you want something based on the Objective C model, I'm sorry, but I cannot help you.
Tom
This answer is correct for C functions. The answer for Objective-C methods is similar, but the syntax is considerably different.
Adam Rosenfield
@Thanks: 'static' means something different here than it does in Java. In this case, 'static' just means that the functions have internal linkage, i.e. they are only visible to other functions within the same file. There are no classes involved here, and there are thus no instance variables.
Adam Rosenfield