Objective-c "class method/Object Method-Anonymous class-new&alloc init difference"

Source: Internet
Author: User
Tags anonymous
———————————————————————————————————————————
Class method


① class Method:

+ The beginning of the method (defined as the process form and the object method, just the + start, which is the only difference)

The invocation of the class method:

[Class name Method name];

② Object methods:

-Methods to begin with

Invocation of the object method:

[Instance object name Method name];

★ Code Comparison Study:

There is a dog class in which there is an object method:

-(void) run; Object methods

To call the Run method,

Dog *dog = [dog new];
[Dog run];


There is another class method in the dog class:

+ (void) run; Class method

To call the Run method,

[Dog Run];


¡ï ★ In the above description, we can see that the name of the two methods are run, but only the previous symbol is different, one is +, the other is--so that the wording of the child can be, he said the different methods, we can image as the "gender" difference of the two methods. Object methods require the creation of an instance object to be called, but the class method can be called directly from the class name. The advantage of a class method is that it does not need to allocate heap memory (because class method calls do not need to create space), saving memory space.


———————————————————————————————————————————
Class method Usage Considerations

① class methods can have the same name as Object methods (instance methods) and do not interfere with each other.
The ② class method can inherit from the parent class, and subclasses can override the class method.
The ③ class method and the object method are the same from the @interface ... @end declaration, in the @implementation ... @end inside the realization.
The ④ class method can only be called by the class name, and the instance object name invocation is not possible. Object methods are also so that object methods can be called only by the instance object name, not by the class name.
⑤ uses self in the class method, and the self executes the class object instead of the instance (instance object)

Example: (here I wrote the header and source files together for easy observation)

#import <Foundation/Foundation.h>

@interface Caculator:nsobject
-(int) add: (int) NUM1 andNum2: (int) num2;
+ (int) add: (int) NUM1 andNum2: (int) num2;
@end

@implementation Caculator
-(int) add: (int) NUM1 andNum2: (int) num2
{
return num1+num2;
}
+ (int) add: (int) NUM1 andNum2: (int) num2
{
return num1+num2;
}
@end

int main (int argc, const char * argv[]) {
@autoreleasepool {
Caculator *caculator=[caculator New];
int result1=[caculator Add:12 andnum2:13];

int result2=[caculator add:22 andnum2:15];

NSLog (@ "%d,%d", RESULT1,RESULT2);
}
return 0;
}


Analysis: Above is a caculator class, and then wrote a class method and an object method, obviously in addition to the method name on the header to identify what exactly is the method of the symbol, the two methods are the same name (the method names are add:andnum2:), We use an instance object and the class name to call each of these two methods, which are clearly correct and do not affect each other.

Then we add an object method to the method declaration above (which is not listed above, it needs to be written by the reader himself), such as:-(int) Jian: (int) NUM1 andNum2: (int) num2; This is what we consider to be a subtraction object method. (The implementation part writes itself) and then we use the class name to call it: [Caculator jian:14 andnum2:12];
Obviously this is wrong, system error: No known class method for selector ' jian:andnum2: '. This sentence tells us that the system does not know the class method named ' Jian:andnum2: '.


———————————————————————————————————————————
Summary of calls and essentials for class methods

This section is designed and validated to call this knowledge point for class methods.
First we should be clear that the class method is flexible, we have designed two large aspects to study the invocation of the class method.

(1) ★ For the same class of ★
The ① object method can be called within the class method (for the Class)
The inner of the ② class method can be used to invoke another class method of the same kind (class-a class)
③ object methods can be called inside of a class method (class-to-pair)

(2) ★ for different classes ★ (Example two classes: Class A and Class B)
The ①a of the object method can call the class method of B (for Class)
The ②a class method can be called within the class method of B (class-A class)
③a of the class method can invoke the object method of B (class-to-pair)

In order to verify the above 6, I have designed and implemented the following program. (This program writes the Declaration and implementation of two classes (car and dog) together for easy observation)

#import <Foundation/Foundation.h>

@interface Car:nsobject
-(void) C1;
+ (void) C2;
+ (void) C3;
+ (void) Test: (dog *) Dog;
@end

@implementation Car
-(void) C1
{
NSLog (@ "Here is the object method for car C1. We'll call one of the class method C2 in car below. ");
[Car C2];
}
+ (void) C2
{
NSLog (@ "Here is the class method for car C2. We will call the dog's class method D1 ") below;
[Dog D1];
}

+ (void) C3
{
NSLog (@ "Here is the class method for car C3. We will call the dog's Object Method D4 ") below;
Dog *dog11=[dog New];
[Dog11 D4];
}

+ (void) Test: (dog *) Dog
{
[Dog D2];

Dog *dd=[dog New];
[DD D2];
}
@end

@interface Dog:nsobject
+ (void) D1;
-(void) D2;
+ (void) D3;
-(void) D4;
@end

@implementation Dog
+ (void) D1
{
NSLog (@ "This is the class method of dog D1. We will call the dog's class method D3 ") below;
[Dog D3];
}
-(void) D2
{
NSLog (@ "This is the object method of dog D2. We will call the car's class method C3 ") below;
[Car C3];
}
+ (void) D3
{
NSLog (@ "This is the class method of dog D3. We will call the dog's object Method D2 ") below;
Dog *dd1=[dog New];
[Dd1 D2];
}
-(void) D4
{
NSLog (@ "Here is the object method of dog D4. ");
}
@end

int main (int argc, const char * argv[]) {
@autoreleasepool {
Car *car=[car New];
[Car C1]; ★ ¡ï Breakpoint Setting at ★
}
return 0;
}


The above program reader can copy to verify that the whole process is this:

Call car's Object method (C1) To call car's class method within a method (C2)
Call car's class method (C2) to call the dog's class method within a method (D1)
Call dog's class method (D1) to call the dog's class method within a method (D3)
Call the dog's class method (D3) to call the dog's object method within the method (D2)
Call Dog's Object method (D2) to call car's class method within a method (C3)
Call car's class method (C3) to call the dog's object method within a method (D4)

We can set the breakpoint in the main function in the appropriate position, and then step into to look at the whole process of the procedure, observe the process of jumping. Easy to understand.


Again, because what we're learning here is the invocation of a class method, so about "another object method that calls a within an object method of a" (pair-and-pair) and "object method that calls B inside an object method of a" (-----YES) we do not verify, of course, the result is certain, You can also call each other. Interested students can go and verify.


¡ï ★ Also explain these situations:

Other object methods can be called in the ★//object method
(1) Create an object within the current object method (either the current class instance object or an instance object of another class), using the newly created object to invoke the object method
(2) You can use self
(3) The object is passed as a parameter of the method and can be invoked using the passed object.

★//other class methods can be called in a class method
(1) The class method can be called directly using the class name (or other class name)
(2) You can use self

(in addition, access to instance variables is not allowed in class methods (that is, attribute members are not allowed in the declaration of the Class), as shown below)


_speed is a property member of the car class declaration, which is not allowed in the class method. Because the calling class method does not allocate storage space, the heap area is empty, so the value cannot be stored, so it cannot be accessed.

★//can call an object method in a class method
(1) The object is passed as a parameter of the method.
(2) You can create an object and then call
(Image below)


The last point to note is that the class method cannot invoke itself, otherwise there will be a dead loop (it cannot be controlled by itself to terminate the loop).   (in the following figure, the T1 is called again inside the class method T1, so once in the main function [Car T1]; , then the loop will not terminate)


I also went to verify that the object method can be inside to call itself, will be wrong, this is very boring, we do not have to verify the ~


———————————————————————————————————————————
An application of the class method (IPhone color)

#import <Foundation/Foundation.h>
typedef enum {KCOLORWHITE,KCOLORBLACK,KCOLORTHJ} Color;

@interface Iphone:nsobject
{
@public
Color _color;
}

+ (NSString *) Togetiphonecolor: (color) color;
The return value type needs to be a string type

@end

@implementation IPhone
+ (NSString *) Togetiphonecolor: (color) color
{
NSString *str;//We need a string variable to receive the returned value
The switch statement is used to determine what color the code represents, and then convert it to a Chinese character string to return
switch (color) {
Case Kcolorwhite:
str=@ "White";
Break
Case Kcolorblack:
str=@ "BLACK";
Break
Case KCOLORTHJ:
str=@ "Local tyrants Gold";
Break
Default
Break
}
return str;
}
@end

int main (int argc, const char * argv[]) {
@autoreleasepool {

We need a way to display the color of the cell phone, so this method only needs to pass the value to the inside, we need to convert the value of our defined enumeration type to a character that can be understood to represent the color. This place does not need to create objects, so use the class method. We call the class method to receive and process a color, finally return a value of the string type, and then use a string variable to receive the value, and then output this value, this is the whole idea
NSString *str=[iphone TOGETIPHONECOLOR:KCOLORTHJ];
NSLog (@ "%@", str);
}
return 0;
}


———————————————————————————————————————————
The concept and use of anonymous classes

#import <Foundation/Foundation.h>
#import "Car.h"
int main (int argc, const char * argv[]) {
@autoreleasepool {
① use anonymous classes to invoke methods
[[Car New] start];//using an anonymous class can invoke the method (in fact, it may be a bit awkward to understand here, what is called anonymous class, not anything else.) We can understand for the time being that when we first saw new, we created the instance object, and now we have the memory space initialized, but there is no instance object, so it can't be called an anonymous object, so this thing appears in the class, it is called anonymous class. New is a method)

[[[Car alloc]init]start];//This sentence is equivalent to [[Car new] start]; , we know that new has done two things, one is allocating storage space (Alloc), and the other is initialization (init). New is the combination of alloc and init, usually because of convenience, we have been using new, in fact, both of the same writing.
[[[Car alloc]init]stop];

② use anonymous classes to access instance variables (member variables)
[Car new]->_speed=100;
NSLog (@ "speed:%d", [Car new]->_speed);
Output speed:0
For access to instance variables with anonymous classes (member properties), ★ Access only once ★, our first access to set _speed value is 100, but the output is equivalent to another visit, when there is no value set, so the output system automatically initialize the value, that is, 0
}
return 0;
}

Anonymous classes are classes that cannot have names, they cannot be referenced, and can only be declared with a new statement when they are created. The declaration of an anonymous class is made at compile time, and instantiation occurs at run time. This means that a new statement in the For loop creates several instances of the same anonymous class, rather than creating an instance of several different anonymous classes.
★ The above sentence is very good, summarized as: compile-time declaration, run-time instantiation.


———————————————————————————————————————————
The difference between new and Alloc/init

In the above section, we have a new understanding of Neo, and now I would like to focus on explaining the similarities between the two.

1. New is rarely used in real-world development, and the general creation of objects sees all [[ClassName alloc] init]
But it doesn't mean you won't be exposed to new, and you'll see [ClassName new] in some code,
There is also the possibility of being asked this question when you go to an interview.
2. So what's the difference between them?
We look at the source:

+ NEW
{
ID newObject = (*_alloc) ((Class) self, 0);
Class Metaclass = self->isa;
if (class_getversion (Metaclass) > 1)
return [NewObject init];
Else
return newObject;
}

And alloc/init like this:
+ Alloc
{
Return (*_zonealloc) ((Class) self, 0, malloc_default_zone ());
}
-Init
{
return self;
}

Through the source we find that [className new] is basically equivalent to [[ClassName alloc] init];
The difference is that the zone is used when alloc allocates memory.
It (zone) is to allocate memory to the object, the associated object is allocated to an adjacent memory area, so that the call to consume a very small cost, improve the program processing speed;

3. Why is it not recommended to use new?
I don't know if you've found it: if you use new, the initialization method is fixed and can only call init.
And what do you want to call initxxx do. No way. It is said that the original design was completely borrowed from the Smalltalk syntax.
Legend has it that time has Allocfromzone: This method,
But this method needs to pass a parameter id mycompanion = [[Theclass allocfromzone:[self Zone]] init];
This method looks like this:

+ Allocfromzone: (void *) Z
{
Return (*_zonealloc) ((Class) self, 0, z);
}

It was later simplified to the following:
+ Alloc
{
Return (*_zonealloc) ((Class) self, 0, malloc_default_zone ());
}

However, there is a problem: This method simply allocates memory to the object and does not initialize the instance variable.
is not going back to the new way of handling: implicitly calling the Init method inside a method.
Later it was found that "show calls are always better than implicit calls", so the two methods were later separated.

¡ï ★ In summary, new and alloc/init are functionally almost identical, allocating memory and completing initialization.
The difference is that the initialization can only be done with the default Init method in new mode,
Alloc can be used in other customized initialization methods ★


———————————————————————————————————————————

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.