[iOS] Category VS Extension principle

(a) Category

1, what is Category?

Category is a language feature that is added after Objective-C 2, and other categories of the population are actually category. The main function of category is to add methods to existing classes. In addition, Apple also recommended the use of two other category scenarios.

The implementation of the class can be separated in several different files. There are several obvious advantages of doing so.
  • Can reduce the volume of a single file
  • Different functions can be organized into different category
  • Can be completed by a number of developers to a class
  • You can load the desired category
  • Declare private method

Apple SDK in a large area of the use of category this feature. For example, UIKit in UIView. Apple the different features of API were classified, including UIViewGeometry, UIViewHierarchy, UIViewRendering, etc..

However, in addition to the recommended use of Apple scenarios, the majority of developers to open the brain hole, but also derived a few other category use scenarios:

  • Simulation of multiple inheritance (in addition to simulate multiple inheritance as well as protocol)
  • Open the framework private method

2, category features

  • Category can only extend an existing class and cannot extend the member variable.
  • Category can also add attributes, but only @property will generate setter and getter statement, will not generate setter and getter implementation and member variables.
  • If the method in category and the class have the same name, the runtime will call the category method. In other words, the category method overrides the original method in the class. So try to ensure that the development of the classification method and the original method in the same class. The solution to avoid this is to add a prefix to the name of the taxonomy. Such as category_.
  • If there is a method with the same name in multiple category, which method is called by the compiler in the end of the run, the last method involved in the compilation is called.

As shown below, two category (one and two) are added to the UIView, and a method named log is added to the two categories:

[iOS] Category VS Extension principle
[iOS] Category VS Extension principle

The two category.H files are introduced in viewController. Call log method:

[iOS] Category VS Extension principle
call category method

When compiling the sequence as shown in the following figure, call the UIView + one.m log method as follows:

[iOS] Category VS Extension principle
compiler order
[iOS] Category VS Extension principle
call results

Move the UIView + one.m to UIView + two.m, call the UIView + two.m log method, as shown below:

[iOS] Category VS Extension principle
compiler order
[iOS] Category VS Extension principle
call results

3, call priority

Classification (category) > class > superclass. That is, to call the cateory method, and then call this method, and finally call the parent method.

Note: category is loaded at run time, not at compile time.

4. Why can’t category add member variables?

The Objective-C class is represented by the Class type, which is actually a pointer to the objc_class structure. It is defined as follows:

Typedef struct objc_class *Class;

The definition of the objc_class structure is as follows:

Struct objc_class {Class isa OBJC_ISA_AVAILABILITY; #if __OBJC2__ Class super_class! OBJC2_UNAVAILABLE const char *name; / / parent / class name long version OBJC2_UNAVAILABLE; OBJC2_UNAVAILABLE; / / version information, the default is 0 long info OBJC2_UNAVAILABLE; / / information for runtime use some identification long instance_size OBJC2_UNAVAILABLE; / / the class instance variable size struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; / / the member variables of a class objc_method_list list struct * * methodLists OBJC2_UNAVAILABLE; / / objc_cache *cache method definition list struct OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE / / cache method; / / #endif} OBJC2_UNAVAILABLE protocol list;

In the objc_class structure above, Ivars is a pointer to the objc_ivar_list (member variable list); methodLists is a pointer to the objc_method_list pointer. In Runtime, the size of the objc_class structure is fixed, it is not possible to add data to the structure, only to modify. So Ivars is pointing to a fixed area, can only modify the member variable value, can not increase the number of member variables. MethodList is a two-dimensional array, so you can modify the value of *methodLists to increase member method, although no way extended memory area methodLists points, but you can change the value of the memory area (storage pointer). Therefore, you can dynamically add methods, can not add member variables.

5, category can add attributes?

Category cannot add a member variable (instance variables), so how can you add attributes (property)?

We’re going to start with the structure of Category:

Typedef struct category_t {const char *name; / / the name of the class classref_t CLS struct method_list_t; / / *instanceMethods; all //category to add a list of struct method_list_t *classMethods instance method; //category add all kind of method is the list of struct protocol_list_t *protocols; all the //category protocol list struct property_list_t *instanceProperties;} all properties category_t added in //category;

From the definition of Category can also be seen as Category (can add instance methods, class methods, and even the realization of the agreement, add attributes) and can not (can not add instance variables).

But why many people on the Internet say that Category can’t add attributes?

In fact, Category actually allows you to add attributes, you can use the same @property, but will not generate _ variables (underlined member variables), will not generate, add getter and setter attribute so while adding attributes, also cannot use the grammar to call getter and setter method (in fact, grammar can be write, only at runtime to invoke the method when the reported methods can not find the error, below). But in fact, you can use runtime to achieve Category to add new attributes to existing classes and generate getter and setter methods. Details can be seen before the article Feng brother: “iOS four of the Runtime: related objects”

[iOS] Category VS Extension principle
add property to category
[iOS] Category VS Extension principle
call category in the setter property (report method can not find the error)
[iOS] Category VS Extension principle
call category in the getter property (report method can not find the error)

Need to pay attention to two points:

  • 1), the category method is not completely replace the original “class has some methods, that is to say if the original class has category and methodA, then added category completed, two methodA will list class.
  • 2), the category method is put in front of the new list of methods, and methods of the original class is on the list behind the new method, this method also is what we usually say category will cover off the original class of the same name, this is because the runtime when the search method was to follow the order the list of search methods, methods, it just to find the corresponding name will give up, but there may be the same name as the method behind.

(two) Extension

1, what is extension

Extension is known as extension, extension, anonymous classification. Extension looks like an anonymous category, but extension and category are almost entirely two things. Unlike category, extension is not only able to declare methods, it can also declare properties, member variables. Extension is generally used to declare private methods, private attributes, private member variables.

2, the existence of extension form

Category is a file with.H and.M files. But extension is not. Extension exists only in a.H file, or extension can only be parasitic on a class of.M files. For example, the viewController.m file is usually parasitic such a thing, in fact, this is a extension:

@interface ViewController () @end

Of course, we can also create a separate extension file, as shown below:

[iOS] Category VS Extension principle
[iOS] Category VS Extension principle
[iOS] Category VS Extension principle

UIView_extension.h declaration method:

[iOS] Category VS Extension principle

Import UIView_extension.h file for use:

[iOS] Category VS Extension principle

Note: extension is not commonly used in the form of a separate.H file exists, but parasitic in the class.M file.

(three) the difference between category and extension

Is the difference between category and extension, we can derive an obvious fact, extension can add the instance variables, while category is unable to add instance variables (as in the operation period, the memory layout object has been determined, if you add an instance variable will destroy the internal layout, the compiled language is a disaster the).

  • Extension is a part of the class during the compile time, but the category is completely different, it is in the run time. Extension in the compiler and the first file in the @interface as well as the realization of the file in the @implement together to form a complete class, it, extension with the generation of the class, but also with the demise of.
  • Extension is generally used to hide the private information, you must have a kind of source for a class to add extension, so you can not add the class system such as NSString extension, unless the subclass to add extension. The category does not need to have a class of source code, we can provide the class to add category.
  • Extension can add instance variables, and category cannot.
  • Both extension and category can add attributes, but the properties of category cannot generate member variables and the implementation of getter and setter methods.

The VV / wood son (author Jane)
PS: as non specified, all articles are original works, the copyright of the author of all, reproduced please contact the author authorized, and indicate the source, all rewards are all belong to me!

If you are a iOS developer, or interested in this article, please pay attention to me, the follow-up will update more related articles! Coming soon!

Reference article

Detailed description of the iOS
Objective-C Category and related objects to achieve the principle of Category