In-depth objective-C Dynamic Features

Source: Internet
Author: User

Objective-C has a lot of dynamic features. Basically, it is also often mentioned and used with dynamic types (dynamic typing) and dynamic binding (dynamic binding) and dynamic loading (dynamic loading ).

These dynamic features are commonly used in cocoa program development. After that, OC also provides a wealth of runtime features at the underlying layer, for example, enumeration class attribute methods and obtaining method implementation. Although these lower-level running features are basically not needed in common cocoa development, in some cases, if you know these features and use them properly, you will often get twice the result with half the effort ~

Dynamic Features

1. Dynamic type

That is, the type of the object is determined at runtime. This kind of dynamic feature is very common in daily applications, simply put, it is the ID type. The ID type is a common object class, and any object can be referred to by the ID pointer. In actual use, introspection is often used to determine the actual class of the object:

id obj = someInstance;  if ([obj isKindOfClass:someClass])  {    someClass *classSpecifiedInstance = (someClass *)obj;    // Do Something to classSpecifiedInstance which now is an instance of someClass    //...}

-isMemberOfClass:YesNSObjectTo determineNSObjectWhether the object is a member of a class. Similar-isKindOfClass:To determine whether an object is a member of a class or its subclass. These two methods are typical introspection methods. After an object is determined to be a member of a certain type, it can be forcibly converted to continue the subsequent work.

2. dynamic binding

Based on the dynamic type, the type of an instance object is determined after it is determined. The attributes of the object and the Response Message are also completely determined, which is dynamic binding. Before continuing, You need to clarify the concept of messages in objective-C. Due to the dynamic characteristics of OC, the concept of "function" is rarely mentioned in OC, traditional Functions usually package the parameter information and function implementation into the compiled source code during compilation, while the message mechanism is most often used in OC. Call an instance method to send a message to the instance pointer. After receiving the message, the instance looks for a method to respond to the message from its own implementation.

Dynamic binding: After the instance class is determined, some attributes and corresponding methods are bound to the instance. The attributes and methods mentioned here include the newly added implementations that are not implemented in the class, but are required at runtime. At the cocoa layer, we generally send-respondstoselector: Or-instancesrespondtoselector: To a nsobject object to determine whether the object can respond to a sel. Before the OC message forwarding mechanism is triggered, the + resolveclassmethod: And + resolveinstancemethod of the corresponding class will be called. In this case, the opportunity is to dynamically add new methods to the class or instance, that is, the implementation of classes can be dynamically bound. Example:

Void dynamicmethodimp (ID self, Sel _ cmd) {// implementation ....} // this method is called before OC message forwarding takes effect + (bool) resolveinstancemethod :( SEL) Asel {If (Asel ==@ selector (resolvethismethoddynamically )) {// Add a void implementation to [self class] And the SEL name is Asel. The specific implementation content is dynamicmethodimp class_addmethod ([self class], Asel, (IMP) dynamicmethodimp, "[email protected]:"); Return yes;} return [Super resolveinstancemethod: Asel];}

Of course, it can also be called wherever neededclass_addMethodOrmethod_setImplementation(Add implementation for the former, and replace implementation for the latter) to meet the dynamic binding requirement.

3. Dynamic Loading

It is easy to understand how to load the required resources as needed. For iOS development, it is basically adapted according to different models. The most typical example is to load the @ 2x image on the retina device, while loading the source image on some older normal screen devices. With the release of the retina iPad and the emergence of the retina Mac, this feature is expected to be used more and more.

In-depth runtime features

Basic Dynamic features are frequently used in conventional cocoa development, especially dynamic types and dynamic binding. Because cocoa programs use the Protocol-delegate design pattern extensively, most of the delegate pointer types must be IDs, in Java, this design pattern is called strategy? I am not familiar with Java, please correct it ). Objective-C also has some advanced or lower-level runtime features, which are rarely seen in General Cocoa development and are basically used to compile interfaces of OC and other languages. However, if you understand and use it properly, you can easily solve some difficult problems in cocoa development.

Most of these runtime features are caused/usr/lib/libobjc.A.dylibThis dynamic library provides many APIs for classes, instance members, member methods, and message sending, including obtaining the class instance variable list and replacing the methods in the class, it is very powerful to add variables to class members and dynamically change the implementation of methods. The complete API list and manual can be found here. Although the beginning of the document indicates that it is applicable to Mac OS X objective-C 2.0, because these are the underlying methods of OC, they are also identical for iOS development.

A simple example, for example, when developing a universal application or game, if IB is used to build a large number of custom UIS, one of the important problems facing the transition from iPhone to iPad is how to load interfaces from different nib instances. Before ios5, allUIViewControllerWhen loading with the default Interface (initOrinitWithNibName:bundle:).-loadNibNamed:owner:options:. Because we cannot get-loadNibNamed:owner:optionsTherefore, it is difficult and risky to overload it. Therefore, when using the iPad version of nib, a simple method is to unify all the nib naming methods, and then use the new similar-loadNibNamed:owner:optionsTo replace the original method, and ensure that non-iPad devices still follow the original method.loadNibNamed:owner:optionsMethod. With the OC runtime features, you can easily complete this task.

The Code is as follows:+swizze, Exchange self-implementedloadPadNibNamed:owner:optionsAnd SystemloadNibNamed:owner:options, After allloadNibNamed:owner:optionsAll messages will be sentloadPadNibNamed:owner:options, Which is processed by your own code.

+(BOOL)swizze {    Method oldMethod = class_getInstanceMethod(self, @selector(loadNibNamed:owner:options:));    if (!oldMethod) {        return NO;    }    Method newMethod = class_getInstanceMethod(self, @selector(loadPadNibNamed:owner:options:));    if (!newMethod) {        return NO;    }    method_exchangeImplementations(oldMethod, newMethod);    return YES;}  

loadPadNibNamed:owner:optionsThe implementation is as follows. Note thatloadPadNibNamed:owner:optionsBecause the exchange has been performed before, it is actually sent as the system'sloadNibNamed:owner:options. This completes loading of different resources.

-(Nsarray *) loadpadnibnamed :( nsstring *) Name owner :( ID) Owner options :( nsdictionary *) Options {nsstring * newname = [name stringbyreplacingoccurrencesofstring: @ "@ pad" withstring: @ ""]; newname = [newname stringbyappendingformat: @ "@ pad"]; // determines whether nsfilemanager * fm = [nsfilemanager defamanager manager] exists. nsstring * filepath = [[nsbundle mainbundle] pathforresource: newname oftype: @ "nib"]; // The loadpadnibnamed: Owner: Options called here is actually the method after the switch, that is, loadnibnamed: Owner: Options: If ([FM fileexistsatpath: filepath]) {return [self loadpadnibnamed: newname owner: Owner options: Options];} else {return [self loadpadnibnamed: name owner: Owner options: Options];}

Of course, this is just a simple example, and this function can be implemented in other ways. For example, if you add a category of uiviewcontroller to reload init, this overload is dangerous because you cannot fully understand the implementation of uiviewcontroller, therefore, some existing init Code may not be overwritten due to overload, resulting in unpredictable errors. Of course, there is no problem if you reload the init of Vc in the above example (for VC, The init method will be automatically forwarded as loadnibnamed: Owner: options, therefore, the init method does not do anything more complicated, so it is no problem as long as init is used during VC initialization ). However, this overload cannot be guaranteed to be feasible for other classes. Therefore, it is a good choice to use the above runtime exchange method to implement unknown system methods ~

In-depth objective-C Dynamic Features

Related Article

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.