Class methods vs instance methods

Discussion in 'iOS Programming' started by zijianz, Jul 17, 2012.

  1. zijianz macrumors newbie

    Joined:
    May 21, 2012
    #1
    Hey guys,

    I am a little bit confused about class methods vs instance methods.

    for example we have a calculator. Pushing the operands and the operations from the screen into stack for further calculation, can be done by both way. I mean, each way could work perfectly. Even for some private data, we could use MutableArray Copy.

    My question is how do we choose if it is class mthd or instance mthd, when we want to create our own method? I mean, not those methods who create an obj, or change this variable into an obj type. Just simply our function, like "take this operation/operand sequence and do the calculation". In what circumstance shall we create a class method.
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    Rule of thumb: If you have no reason to make it a class method, make it an instance method.

    Reasons:
    1. Most methods in most classes you'll every write will be instance methods. Learn how to make those effectively, and the reason for using a class method will become clearer.

    2. It's easier to subclass, use protocols, categories, and so on with instance methods.

    3. If it doesn't affect the class as a whole, or all instances of the class in the same way, then it shouldn't be a class method. Creational methods (e.g. see the stringWithXXX methods of NSString) should normally be class methods, since they affect all instances of the class in the same way (i.e. all instances are created from the same creational method in the same way).
     
  3. zijianz thread starter macrumors newbie

    Joined:
    May 21, 2012
  4. PBG4 Dude macrumors 68000

    PBG4 Dude

    Joined:
    Jul 6, 2007
    #4
    Sounds like you may be looking at CalculatorBrain.m from the CS193p / Coding Together iTunes U class?

    If not, look up lectures 4-6 (it's one of these). Mr. Hegarty does an awesome job of explaining Class Methods vs. Instance Methods.

    In one particular example, an immutable array of operations and operands is passed to the CalculatorBrain's runProgram Class method. This immutable array is made into a mutable array which is then passed to another Class method that recursively 'eats' this array until it hits its base case and returns to the runProgram method which returns a (double) result.

    The bonus of having runProgram as a Class method is you don't have to have an instance of CalculatorBrain running in order to evaluate a result. You just need to have an NSArray with operands / operators to pass to the Class method.
     
  5. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #5
    You make it sound like class methods are evil and bad. They are not, and they have their uses.

    I would explain things differently.

    Instance methods are sent to an INSTANCE of a class. An instance of a class is a concrete thing. It has state data that persists for the life of the object. When you send a message to an object, it can use that state data to do things, and it can remember information for later.

    Class methods are sent to the class as a whole. A class is a more abstract concept. Classes do not save state data, at least in Objective C (In other languages like C++, there are class variables that belong to the entire class, but Objective C does not have class variables.)

    An analogy. Imagine a car factory:

    The car factory is the class. The car class has a class method buildCar. The buildCar method takes parameters that tell what color the car should be, how big the engine should be, what options it should have, etc. You sent the car factory (the class) a buildCar message, and it creates and returns an instance of that class (the car factory builds you a car and gives it to you.)

    Once you've created a car, that particular car has state variables that store things like the channel on the radio, the amount of gas left in the tank, the milage ("kilometerage"?) on the odometer, the wear level on the brakes, etc. Different cars will have different values for those variables.

    You can ask an individual car how much gas is left in it's tank. (instance method.) Car A might have a full tank, and car B might be nearly empty.

    However, it would not make sense to ask the car factory how much gas it has in the tank. A car factory doesn't have a gas tank. However, you could ask a car factory about the types of cars that it can build and the options for those cars. That is static information that always holds true for that car factory.

    In addition to "factory methods" (e.g. build me a car), you can use class methods like you use functions in a procedural language. A class method is self-contained. You pass all the parameters into the method that you need in order to do whatever task is required, and you get back a single result (or no result for a void class method.) Once the class method is done executing, there is no state data left to record what happened.

    You could write a math library as class methods, or you could write it as a C function.

    For example, you could write a sine function as a C function:


    Code:
    float sine(float theta)
    {
      return sin(theta);
    }
    
    And you'd call it like this:

    Code:
    x = sine(0);
    
    Or, you could create a Math class, and define a sine class method:

    Code:
    @interface Math: NSObject;
    
    + (float) sine: (float) theta;
    @end
    
    Code:
    @implementation Math
    + (float) sine: (float) theta;
    {
       return sin(theta);
    }
    @end
    
    You'd call the class method like this:

    Code:
    x = [Math sine: 0];
    
    When you call a class method, you put the name of the class as the first thing inside the brackets, and then any parameters. That tells you that the message gets sent to the class, not an instance of the class.
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Your interpretation. Not at all my intent.

    I never said nor suggested otherwise.

    However, I stand by the rule of thumb. If you can't think of a reason to make it a class method, then make it an instance method. The examples you gave of a factory are exactly what I meant: the class acting as a factory means there is a reason to make a class method.

    This does not imply that a factory method should always be a class method, however. It is sometimes useful to have an instance which has factory methods, so the factory method would be an instance method. For example, suppose the class represents car-factories, each one with different production capabilites, different connectivity to resources, etc. Then each instance of a car-factory object has an instance factory-method for making cars. If that seems like a contrived example, the process of making objects is common enough that factory-methods often appear in objects that don't otherwise seem to be factories.

    For a beginner who can't decide between class method and factory method, I don't think there's a simpler heuristic than the one I gave.
     
  7. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #7

    Something I would add is that it is sometimes useful to make global utility functions as class methods. That lets you use the clearer, more familiar Objective C syntax for your calls (where each parameter has a label) without having to create and manage an instance of an object in order to do it.

    The way I would explain it is that class methods are for:

    -factory methods that create objects (as you say, sometimes an instance method can serve as a factory method, but that is the exception.)

    -In place of global C functions, where all the exchange with the caller can be done with parameters and/or a return value, and you don't need to read or write any persistent state data.
     
  8. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #8
    I'd add singletons to the list. For examples, see NSFileManager, NSProcessInfo, NSUserDefaults.
     
  9. Duncan C macrumors 6502a

    Duncan C

    Joined:
    Jan 21, 2008
    Location:
    Northern Virginia
    #9

    Good point. Class methods are the normal way to request a pointer to a singleton.
     

Share This Page