Method and related Method Analysis

Source: Internet
Author: User
Method and related Method Analysis

Reprinted please note source http://blog.csdn.net/uxyheaven

This article will explore how Methods functions are implemented in objc.

First, let's take a look at the definition of the method. method is an objc_method struct.

Objc_method

Objc_method is the description of a class method.

The definition is as follows:

Method class_getinstancemethod (class CLs, Sel SEL) {If (! CLS |! Sel) return NULL; return look_up_method (CLS, Sel, yes/* cache */, yes/* resolver */);} static method look_up_method (class CLs, Sel, bool withcache, bool withresolver) {method meth = NULL; // 1. if (withcache) {meth = _ cache_getmethod (CLS, Sel, & _ objc_msgforward_internal); If (meth = (method) 1) {// cache contains forward ::. stop searching. return NULL;} // 2. find your own if (! Meth) meth = _ class_getmethod (CLS, Sel); // 3. forward if (! Meth & withresolver) meth = _ class_resolvemethod (CLS, Sel); Return meth ;}
IMP class_getmethodimplementation (class CLs, Sel name)

Return the call address of the CLS name method.

The definition is as follows:

Bool class_addmethod (class CLs, Sel name, IMP imp, const char * types) {If (! CLs) return no; rwlock_write (& runtimelock); imp old = addmethod (newcls (CLS), name, IMP, types?: "", No); rwlock_unlock_write (& runtimelock); return old? No: Yes;} static imp addmethod (class_t * CLs, Sel name, IMP imp, const char * types, bool replace) {imp result = NULL; rwlock_assert_writing (& runtimelock ); assert (types); Assert (isrealized (CLS); method_t * m; // 1. find the method if (M = getmethodnosuper_nolock (CLS, name) in the method list of your class {// already exists if (! Replace) {// do not replace, return M-> imp result = _ method_getimplementation (m);} else {// replace, set the m method of Cls to IMP result = _ method_setimplementation (CLS, M, IMP);} else {// fixme optimize // 2. create a method_list_t node method_list_t * newlist; newlist = (method_list_t *) _ calloc_internal (sizeof (* newlist), 1); newlist-> values = (uint32_t) sizeof (method_t) | fixed_up_method_list; newlist-> COUNT = 1; ne Wlist-> first. Name = Name; newlist-> first. types = strdup (types); If (! Ignoreselector (name) {newlist-> first. IMP = imp;} else {newlist-> first. IMP = (IMP) & _ objc_ignored_method;} // 3. add newlist to the CLS method list bool vtablesaffected = no; attachmethodlists (CLS, & newlist, 1, no, & vtablesaffected); // 4. refresh the CLS cache flushcaches (CLS); If (vtablesaffected) flushvtables (CLS); Result = NULL;} return result ;}

When class_addmethod is used, replace = No, so the CLS fails to be added when this method already exists.

IMP class_replacemethod (class CLs, Sel name, IMP imp, const char * types)

Replace the CLS name pointer

Void method_exchangeimplementations (method m1_gen, method m2_gen) {method_t * m1 = newmethod (m1_gen); method_t * M2 = newmethod (m2_gen); If (! M1 |! M2) return; rwlock_write (& runtimelock); If (ignoreselector (M1-> name) | ignoreselector (m2-> name) {// ignored Methods stay ignored. now they're both ignored. m1-> imp = (IMP) & _ objc_ignored_method; M2-> imp = (IMP) & _ objc_ignored_method; rwlock_unlock_write (& runtimelock); return ;} // The implementation pointer imp m1_imp = m1-> IMP; M1-> imp = m2-> IMP; M2-> imp = m1_imp; if (vtable_containsselector (M1-> name) | vtable _ Containsselector (m2-> name) {// don't know the class-will be slow if vtables are affected // fixme build list of classes whose methods are known externally? Flushvtables (null);} // fixme catch nsobject changing to custom RR // CLS-> setcustomrr (); // fixme update monomorphism if necessary rwlock_unlock_write (& runtimelock );}

Actually, there is a pitfall here. How does the method come from? Through class_getinstancemethod, if the subclass does not exist, the method of the parent class will be returned. If method_exchangeimplementations is used at this time, will replace the method for replacing the parent class, which is obviously not what we want. so, this is what we usually write.

IMP method_getImplementation(Method m){    return _method_getImplementation(newmethod(m));}static IMP _method_getImplementation(method_t *m){    if (!m) return NULL;    return m->imp;}
IMP method_setimplementation (method, IMP)

Set the new implementation pointer of the method and return the old implementation pointer.

const char *method_getTypeEncoding(Method m){    if (!m) return NULL;    return newmethod(m)->types;}

Method and related Method Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.