Question

I understand a class is actually an object / typedef of struct (objc_class*). Each class has a "backing" meta class, which in turns has a isa pointer pointing to the meta class of NSObject.

And NSObjectbasically has a isa pointer pointing back to itself.

And we could get a hold of the meta class via this line:

objc_getMetaClass("<CLASS_NAME>");

I hope my understanding of meta class is not off here so far (please correct me if it is).

My questions are:

1.)

When would we need to deal with meta class? Could you please cite an example / a scenario in code when we might need to?

2.)

Background:

I was thinking freely about third party libraries and how they are structured.

Usually they provide you with a class method and return you a class and all other methods are private / "hidden". And most of the time, while they can be subclassed but since we do not know the init method, it would be of no use to subclass.

And suddenly I began thinking about Objective-C Category and thus leading me to think of Objective-C meta class.

And this leads to my question #2:

Is it possible to break this structure by making use of Objective-C Category and / or with the use of meta class (by grabbing a hold of it and insert a class method straight there in the meta class)? Or even look up the name of their instance methods that are private?

My intention here is not to "break" anything, I am just very curious as to how "unbreakable" these third party libraries are structured and if their structures cannot be "broken" via the use of Category and Meta Class.

@Leo Natan:

1.)

What is method_*()?

2.)

For the love of Objective-C Runtime:

Could you cite an example implementation-swizzling an instance method, let say,

(I am not sure if this method is a good example, for we could override it in the first place)

NSArray's -count instance method (let’s make it so that it returns always count 100, for example)

3.)

So in theory all classes (including all third party libraries) can be break (broken)? Other words, there is no way to create a „call-only-this-class-method-or-you-cannot-use-me“ API / library?

Thanks a lot.

Was it helpful?

Solution

The meta class is useful when wishing to view, add or modify class methods and class-level information.

For example,

    IMP myIMP = imp_implementationWithBlock(^(id _self, NSString *string) {
        NSLog(@"Hello %@", string);
    });
    Class cls = objc_getMetaClass("NSString");
    class_addMethod(cls, @selector(test:), myIMP, "v@:@");
    [NSString test:@"lala"];

To get instance methods, you use class_copyMethodList() on the class returned by class method on an object or NSClassFromString(). You will get an array of all the instance methods defined by the class (but not of its superclass!). You can then use the various method_*() methods to retrieve information and possibly even modify these methods (like implementation swizzling).

You can call class_copyMethodList() on the meta class to get all the class methods defined.

To address your "Leo" questions,

1. Please read the Objective C Runtime Reference. You can find a section of method_ functions dealing with Method structs.

2. See tutorial on implementation swizzling.

3. Using Objective C, everything is available to the runtime. It goes without saying, that with great power comes great responsibility. The Objective C runtime is very powerful. These swizzles are very dangerous and usually not recommended.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top