0

What is the method "class" for, as used in [Rectangle class]? Does it create an instance of Rectangle? I thought that was

Rectangle *aRectangle = [[Rectangle alloc] init]. 

Why/When would I ever use [Rectangle class]?

1 Answers1

1

Here are probably the two most common uses for [Rectangle class]:

  1. You can use [Rectangle class] to check whether an object is an instance of Rectangle (or an instance of a subclass of Rectangle):

    if ([object isKindOfClass:[Rectangle class]]) {
        Rectangle *rect = (Rectangle *)object;
        // ... use rect
    }
    

    But if you just have one message to send, it might be better to just check whether the object understands the message you want to send it:

    if ([object respondsToSelector:@selector(area)]) {
        double area = [object area];
        // etc.
    }
    
  2. You can use the class object to create an instance of the class:

    Class rectangleClass = [Rectangle class];
    Rectangle *rectangle = [[rectangleClass alloc] init];
    

    Why would you want to do that? Well, if you know the class explicitly at the location (in your code) where you want to create it, you wouldn't. You'd just say [[Rectangle alloc] init], for example.

    But consider UIView. Every UIView creates and manages a CALayer. By default, it creates an instance of CALayer, but you might want your view to use a CAShapeLayer (example) or a CAGradientLayer (example) instead. You need a way to tell UIView to create an instance of a different class.

    You can tell your UIView subclass what kind of layer to create by overriding the layerClass class method:

    @implementation MyShapeView
    
    + (Class)layerClass {
        return [CAShapeLayer class];
    }
    

    When it's time for a MyShapeView to create its layer, it'll send itself layerClass and create an instance of whatever class it gets back. The code probably looks something like this:

    @implementation UIView {
        CALayer *_layer;
    }
    
    - (CALayer *)layer {
        if (_layer == nil) {
            _layer = [[[self layerClass] alloc] init];
            _layer.delegate = self;
        }
        return _layer;
    }
    
Community
  • 1
  • 1
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
  • Thank you! So [Rectangle class] returns the class "Rectangle" then? Or does it create a new class called Rectangle? If the former, what's the difference between saying [Rectangle class} and just Rectangle? And what do you mean by "the class object"? – Jameson Rader Feb 17 '15 at 03:56
  • Lastly, what exactly are you doing here: `Class rectangleClass = [Rectangle class]; Rectangle *rectangle = [[rectangleClass alloc] init]; ` Why isn't it: `Class rectangleClass = [Rectangle class]; Rectangle *rectangle = [[Rectangle alloc] init];` What is rectangleClass? – Jameson Rader Feb 17 '15 at 04:37
  • `[Rectangle class]` returns an object representing the `Rectangle` class. If you call it repeatedly, you will get the same object each time. By saying `[[rectangleClass alloc] init]`, you are allowing the class to be changed at runtime, instead of being fixed at compile time. Since `rectangleClass` is a variable, it could be assigned a different class object (presumably, a class object representing a subclass of `Rectangle`). – rob mayoff Feb 17 '15 at 05:23