[Proficient objective-c] object and message delivery
Reference book: "Proficient objective-c" "Beauty" Keith Lee
Directory
- Proficient in Objective-c object and message passing
- Directory
- Object
- Creating objects
- Initializing objects
- Refactor the Atom class and create subclasses
- Factory method
- Message delivery
- Send Message
- Message forwarding
- Atom class created in the previous chapter of the Appendix
Object Creation Object
The method used to create class instances (that is, objects) in the NSObject class
+(id) alloc
With the Alloc method, you can create an object, as an example of creating an Atom object
//创建一个属于Atom类的对象,并为它分配一个数据类型为id的变量id atom = [Atom alloc];//与上面语句等价,显示定义变量的类型,失去灵活性,但可以获得静态类型检查Atom *atom = [Atom alloc];
Initializing objects
The Alloc method allocates memory for an object and sets its instance variable to 0, but the Alloc method neither initializes the instance variable of the object to the appropriate value, nor prepares other necessary objects and resources for the object. Therefore, a custom class should also implement a method of completing the initialization process.
The method used to initialize an object in the NSObject class:
-(id) init
The following is an example of the Atom class Init method:
-(id) init{ //调用父类的init方法,结果赋给调用对象 if ((self = [super init])) { //初始化 _chemicalElement = @"None"; } returnself;}
Refactor the Atom class and create subclasses
When the compiler automatically complements a property, it creates a support instance variable scoped to @private and cannot be accessed by subclasses of that class. You can refactor the class to set the scope of the variable to @protected.
@interface Atom : nsobject //Refactoring Atom class, declaring a supported instance variable scoped to @protected{@protectedNsuinteger _protons;@protectedNsuinteger _neutrons;@protectedNsuinteger _electrons;@protected NSString*_chemicalelement;@protected NSString*_atomicsymbol;}properties and methods declared before//@property(ReadOnly) Nsuinteger protons;@property(ReadOnly) Nsuinteger neutrons;@property(ReadOnly) Nsuinteger electrons;@property(ReadOnly)NSString*chemicalelement;@property(ReadOnly)NSString*atomicsymbol;-(Nsuinteger) Massnumber;@end
Create a subclass of the Atom class hydrogen, and use the new initialization method that can accept parameters.
Hydrogen.h
#import "Atom.h"@interface Hydrogen : Atom//声明初始化方法-(id) initWithNeutrons:(NSUInteger)neutrons;@end
Hydrogen.m
#import "Hydrogen.h"@implementation Hydrogen{ @private HydrogenHelper *helper;}//实现初始化方法-(id) initWithNeutrons:(NSUInteger)neutrons{ if ((self = [super init])) { _chemicalElement = @"Hydrogen"; _atomicSymbol = @"H"; _protons = 1; //使用传入参数为实例变量赋值 _neutrons = neutrons; } return self;}@end
Factory method
Factory method refers to a convenient way to create and initialize classes
Declare in Hydrogen.h
+(id) hydrogenWithNeutrons:(NSUInteger)neutrons;
Implemented in HYDROGEN.M
+(id) hydrogenWithNeutrons:(NSUInteger)neutrons{ //创建一个Hydrogen对象并初始化,然后返回这个对象 return [[self alloc] initWithNeutrons:neutrons];}
Then we can do the initialization of the object in two different ways.
//普通方法 Hydrogen *atom1 = [[Hydrogen alloc] initWithNeutrons:1]; //工厂方法 Hydrogen *atom2 = [Hydrogen hydrogenWithNeutrons:2];
Message delivery
Messaging is the mechanism used in OOP to invoke methods in an object. The object (sink) that receives the message determines which method of its instance is called at run time. Instance methods can access instance variables and instance methods of an object.
Send Message
To send a message to an object in the format:
[接收器 消息名称1:参数1 消息名称2:参数2...]
At the same time, OBJECTIVE-C provides language-level support for class methods:
[类名 消息名称1:参数1 消息名称2:参数2...]
The previous one [Hydrogen hydrogenWithNeutrons:2]
was to send a message to the hydrogen class.
Message forwarding
At run time, the sink will determine which method to invoke by interpreting the message. OBJECTIVE-C provides a message-forwarding mechanism that, when an object receives a message that does not match its set of methods, enables the object to execute various logic when it receives unrecognized information, such as sending a message to another receiver capable of responding, or neither processing nor throwing the program out of a run-time error. Swallowed the message silently.
OBJECTIVE-C provides two types of message forwarding options for subclasses of the NSObject class.
Fast forwarding:
//重写NSObject类的该方法,将该方法转发给其他对象,就像是将对象的实现代码与转发对象合并到了一起,类似于类实现的多重继承行为-(id) forwardingTargetForSelector:(SEL)aSelector
Standard (FULL) Forwarding:
//重写NSObject类的该方法,可以让对象使用消息中的全部内容(目标,方法名和参数)-(void) forwardInvocation:(NSInvocation *)anInvocation
The following is a quick forward mechanism for the hydrogen class.
You first need to create a helper class Hydrogenhelper, which handles a method that is not handled by a hydrogen class named factoid.
HydrogenHelper.h
#import <Foundation/Foundation.h>@interface HydrogenHelper : NSObject-(NSString *) factoid;@end
Hydrogenhelper.m
#import "HydrogenHelper.h"@implementation HydrogenHelper-(NSString *) factoid{ return @"The lightest element and most abundant chemical substance.";}@end
Re-update the code for the hydrogen class
@implementation hydrogen //Add instance variable hydrogenhelper{@privateHydrogenhelper *helper;} -(ID) Initwithneutrons: (Nsuinteger) neutrons{if(( Self= [SuperInit]) {_chemicalelement = @"Hydrogen"; _atomicsymbol = @"H"; _protons =1; _neutrons = neutrons;//Create and initialize the Hydrogenhelper objectHelper = [[Hydrogenhelper alloc] init]; }return Self;} +(ID) Hydrogenwithneutrons: (Nsuinteger) neutrons{return[[ SelfAlloc] initwithneutrons:neutrons];}//Override Forwardingtargetforselector for NSObject class: (SEL) Aselector method-(ID) Forwardingtargetforselector: (SEL) aselector{//If the Hydrogenhelper object is capable of processing the message, the message is forwarded to the Hydrogenhelper object if([helper Respondstoselector:aselector]) {returnHelper }return Nil;}@end
In order for the hydrogen class to be able to receive the Factoid method, you need to add a classification in which to declare the Factoid method (no implementation is required)
Atom+helper.h (the automatically created ATOM+HELPER.M can be deleted because no implementation method is required)
#import "Atom.h"//也可以将Atom改为Hydrogen@interface Atom (Helper)//声明factoid方法-(NSString *) factoid;@end
Finally, we can send the Factoid method to the Hydrogen object through the message forwarding function.
Hydrogen *atom = [Hydrogen hydrogenWithNeutrons:2];[atom factoid];
Appendix: The Atom class created in the previous chapter
Atom.h
#import <Foundation/Foundation.h>@interface Atom : NSObject@property(readonly) NSUInteger protons;@property(readonly) NSUInteger neutrons;@property(readonly) NSUInteger electrons;@property(readonlyNSString *chemicalElement;-(NSUInteger) massNumber;@end
Atom.m
#import "Atom.h"@implementation Atom-(id) init{ if ((self = [super init])) { _chemicalElement = @"None"; } returnself;}-(NSUInteger) massNumber{ returnself.protonsself.neutrons;}@end
[Proficient objective-c] object and message delivery