Best way to define private methods for a class in Objective-C

后端 未结 12 1811
小鲜肉
小鲜肉 2020-11-22 14:34

I just started programming Objective-C and, having a background in Java, wonder how people writing Objective-C programs deal with private methods.

I understand there

相关标签:
12条回答
  • 2020-11-22 15:05

    As other people said defining private methods in the @implementation block is OK for most purposes.

    On the topic of code organization - I like to keep them together under pragma mark private for easier navigation in Xcode

    @implementation MyClass 
    // .. public methods
    
    # pragma mark private 
    // ...
    
    @end
    
    0 讨论(0)
  • 2020-11-22 15:07

    If you wanted to avoid the @interface block at the top you could always put the private declarations in another file MyClassPrivate.h not ideal but its not cluttering up the implementation.

    MyClass.h

    interface MyClass : NSObject {
     @private
      BOOL publicIvar_;
      BOOL privateIvar_;
    }
    
    @property (nonatomic, assign) BOOL publicIvar;
    //any other public methods. etc
    @end
    

    MyClassPrivate.h

    @interface MyClass ()
    
    @property (nonatomic, assign) BOOL privateIvar;
    //any other private methods etc.
    @end
    

    MyClass.m

    #import "MyClass.h"
    #import "MyClassPrivate.h"
    @implementation MyClass
    
    @synthesize privateIvar = privateIvar_;
    @synthesize publicIvar = publicIvar_;
    
    @end
    
    0 讨论(0)
  • 2020-11-22 15:09

    You could try defining a static function below or above your implementation that takes a pointer to your instance. It will be able to access any of your instances variables.

    //.h file
    @interface MyClass : Object
    {
        int test;
    }
    - (void) someMethod: anArg;
    
    @end
    
    
    //.m file    
    @implementation MyClass
    
    static void somePrivateMethod (MyClass *myClass, id anArg)
    {
        fprintf (stderr, "MyClass (%d) was passed %p", myClass->test, anArg);
    }
    
    
    - (void) someMethod: (id) anArg
    {
        somePrivateMethod (self, anArg);
    }
    
    @end
    
    0 讨论(0)
  • 2020-11-22 15:10

    You could use blocks?

    @implementation MyClass
    
    id (^createTheObject)() = ^(){ return [[NSObject alloc] init];};
    
    NSInteger (^addEm)(NSInteger, NSInteger) =
    ^(NSInteger a, NSInteger b)
    {
        return a + b;
    };
    
    //public methods, etc.
    
    - (NSObject) thePublicOne
    {
        return createTheObject();
    }
    
    @end
    

    I'm aware this is an old question, but it's one of the first I found when I was looking for an answer to this very question. I haven't seen this solution discussed anywhere else, so let me know if there's something foolish about doing this.

    0 讨论(0)
  • 2020-11-22 15:11

    While I am no Objective-C expert, I personally just define the method in the implementation of my class. Granted, it must be defined before (above) any methods calling it, but it definitely takes the least amount of work to do.

    0 讨论(0)
  • 2020-11-22 15:17

    Defining your private methods in the @implementation block is ideal for most purposes. Clang will see these within the @implementation, regardless of declaration order. There is no need to declare them in a class continuation (aka class extension) or named category.

    In some cases, you will need to declare the method in the class continuation (e.g. if using the selector between the class continuation and the @implementation).

    static functions are very good for particularly sensitive or speed critical private methods.

    A convention for naming prefixes can help you avoid accidentally overriding private methods (I find the class name as a prefix safe).

    Named categories (e.g. @interface MONObject (PrivateStuff)) are not a particularly good idea because of potential naming collisions when loading. They're really only useful for friend or protected methods (which are very rarely a good choice). To ensure you are warned of incomplete category implementations, you should actually implement it:

    @implementation MONObject (PrivateStuff)
    ...HERE...
    @end
    

    Here's a little annotated cheat sheet:

    MONObject.h

    @interface MONObject : NSObject
    
    // public declaration required for clients' visibility/use.
    @property (nonatomic, assign, readwrite) bool publicBool;
    
    // public declaration required for clients' visibility/use.
    - (void)publicMethod;
    
    @end
    

    MONObject.m

    @interface MONObject ()
    @property (nonatomic, assign, readwrite) bool privateBool;
    
    // you can use a convention where the class name prefix is reserved
    // for private methods this can reduce accidental overriding:
    - (void)MONObject_privateMethod;
    
    @end
    
    // The potentially good thing about functions is that they are truly
    // inaccessible; They may not be overridden, accidentally used,
    // looked up via the objc runtime, and will often be eliminated from
    // backtraces. Unlike methods, they can also be inlined. If unused
    // (e.g. diagnostic omitted in release) or every use is inlined,
    // they may be removed from the binary:
    static void PrivateMethod(MONObject * pObject) {
        pObject.privateBool = true;
    }
    
    @implementation MONObject
    {
        bool anIvar;
    }
    
    static void AnotherPrivateMethod(MONObject * pObject) {
        if (0 == pObject) {
            assert(0 && "invalid parameter");
            return;
        }
    
        // if declared in the @implementation scope, you *could* access the
        // private ivars directly (although you should rarely do this):
        pObject->anIvar = true;
    }
    
    - (void)publicMethod
    {
        // declared below -- but clang can see its declaration in this
        // translation:
        [self privateMethod];
    }
    
    // no declaration required.
    - (void)privateMethod
    {
    }
    
    - (void)MONObject_privateMethod
    {
    }
    
    @end
    

    Another approach which may not be obvious: a C++ type can be both very fast and provide a much higher degree of control, while minimizing the number of exported and loaded objc methods.

    0 讨论(0)
提交回复
热议问题