When programming with object-oriented languages such as OC, "object" is a "Basic constructor" (Building Block). developers can store and transmit data through objects. The process of passing data between objects and executing tasks is called "messaing ).
After the application is running, the code that provides relevant support for the application is called "objective-C Runtime Environment" (objevtive-C Runtime ), it provides some important functions that allow objects to pass messages, and contains all the logic used to create a class instance. After understanding the working principles of various parts of the runtime environment, your development level will be further improved.
Article 3: understanding the concept of "attribute"
Property is a feature of OC used to encapsulate data in objects. OC objects usually save the required data as various instance variables. The property also has some access methods setter and getter. This concept has been finalized. developers can enable the compiler to automatically write access methods related to attributes.
The class that describes personal information may store personal names, birthdays, addresses, and other content. You can declare some instance variables in the public section of the class interface:
@interface EOCPerson : NSObject{@public NSString* _firstName; NSString* _lastName;@private NSString* _someInternalData;}@end;
People who have used Java and C ++ are familiar with this method and can define the scope of variables. OC seldom does this. The variable memory layout in this writing method has been fixed during the compilation period. :
For details, see "Deep Exploration C ++ Object Model" http://blog.csdn.net/hherima/article/details/8888539.
If an nsstring * _ dateofbirth attribute is added to the eocperson class, the code needs to be re-compiled; otherwise, an error occurs. For example, the code in a code library uses an old class definition. If the code linked to it uses a new class definition, incompatibility will occur during the runtime. Various programming languages have methods to address this problem. The Objetive-C method is to store the instance variables as special variable, which stores all the offset values for the "class objects. The offset will be searched at runtime. If the class definition changes, the storage offset will change. In this way, the correct offset will always be used whenever the instance variable is accessed. You can even add instance variables to the class at runtime. This is a solid "application binary interface (ABI)
@ Property syntax, which can access data encapsulated in objects. Therefore, attribute can also be referred to as an abbreviation, which means that the compiler will automatically generate an access method to access a variable with a given name in a given type. For example:
@interface EOCPerson : NSObject@proterty NSString* firstName;@proterty NSString* lastName;@end
For Class users, the class written in the above Code is equivalent to the following statement:
@interface EOCPerson : NSObject-(NSString*)firstName;-(void)setFirstName:(NSString*)firstName;-(NSString*)lastName;-(void)setLastName:(NSString*)lastName;@end
The access attribute uses the dot syntax. Another advantage of the attribute is that the @ synthesize can be automatically merged. In addition, the @ dynamic keyword can tell the compiler not to automatically generate the attribute access method, which is no longer cumbersome here.
Attribute traits
Attributes have four characteristics: atomicity, read/write permissions, memory management semantics, and Method Name:
1. Atomicity is the atomic trait by default (although there is no atomic trait), nonatmic tells the compiler not to use synchronization locks.
2. read/write permissions: Attributes With read/write attributes have access methods. If the attribute is implemented by @ synthesize, the compiler automatically generates the two methods. Attributes With readonly (read-only) attributes only have the getter method.
3. Memory Management Semantics
● Assign only performs simple value assignment for pure type
● Strong has a relationship. When a new value is set for this attribute, the new value is retained to release the old value.
● Weak is the same as assign, but the attribute values are also cleared when the object is destroyed.
● Unsafe_unretained is the same as assign. It applies to "Object Type", which is the only difference with assign.
● Copy is similar to strong. However, setting setter does not retain a new value, but instead "copy" it ). When the attribute type is nsmutablestring *, the copy feature is required to prevent attributes from being accidentally modified. Refer to objective-C 2.0-(III)-interface and API design, deep copy, light copy http://blog.csdn.net/hherima/article/details/38403277
4. Method Name
● Getter = <Name> specifies the method to be retrieved.
● Setter = <Name> specifies the "setting method" name.
Highlights of this section
● Use the @ property syntax to define the encapsulated data in an object
● "Traits" are used to specify the correct semantics required for data storage.
● When setting the instance variable corresponding to the attribute, you must follow the semantics of the attribute declaration.
● Nonatomic characteristics should be used when developing iOS programs, because atomic will seriously affect performance.
7th: Try to directly access instance variables within the object
When accessing instance variables outside of an object, the attribute should always be used. So inside the object? I strongly recommend that you use direct access when reading instance variables, and use attributes when setting instance variables. The primary reason for writing instance variables through the "setting method" is to ensure that the "Memory Management Semantics" of relevant attributes can be implemented.
Article 8th: understanding the concept of "object equivalence"
The nsobject protocol has two key methods for determining equality:
-(BOOL) isEqual:(id)object;-(NSUInteger)hash;
The default implementation of the nsobject class for these two methods is that the two objects are equal only when the "pointer value" (pointer value, which can be understood as the memory address) is completely equal. If the "isequal:" method determines that two objects are equal, the hash method must return the same value. However, if the hash method of the two objects returns the same value, the "isequal:" method may not consider the two as equal.
First, let's look at the "isequal:" interface. If a class contains three fields: A, B, and C, isequal will compare the three locations one by one, and then return true when the three locations are the same.
Let's take a look at the hash method. The general practice is to hash the fields A, B, and C respectively, and then try again.
-(NSUInteger)hash{NSUInteger firstNameHash = [_firstName hash];NSUInteger lastNameHash = [_lastName hash];NSUInteger ageHash = _age;return firstNameHash ^ lastNameHash ^ ageHash}
This method not only ensures high efficiency, but also enables the generated hash code to be at least within a certain range, without too frequent repetition.
Equality Determination Method for a specific type
In addition to the nsstring mentioned earlier, the nsarray and nsdictionary classes also have judgment methods. The former is "isequaltoarray" and the latter is "isequaltodictionary ".
Except
Execution depth of equality Determination
When you create an equality judgment method, you need to determine whether to judge based on the entire object or based only on several fields. Nsarray checks whether the number of objects contained in the two arrays is equal. If they are the same, the "isequal" method is called on the two objects in each corresponding position, if the objects at the corresponding position are equal, the two arrays are equal, which is called "depth equivalent determination"
Equality of variable classes in containers
Just give an example of nsset.
Step 1: Add a variable array a [@ 1, @ 2] To nsset. Then, an object exists in set, {[@ 1, @ 2]}.
Step 2: Add a variable array B [@ 1, @ 2] To nsset. Because array A and array B are the same, set is still an object, this is also responsible for the set features.
Step 3: Add a variable array C [@ 1] to nsset. Then there are two objects in set: {[@ 1], [@ 1, @ 2]}.
Step 4: change the value of array C to [@ 1, @ 2], so set actually contains two identical objects, {[@ 1, @ 2], [@ 1, @ 2]}. this does not conform to the set feature.
Step 5: copy a set. The content of the new set becomes {[@ 1, @ 2. It seems that the set starts with an empty set and is created by adding new objects to it one by one.
This is because a collect like set should not change its hash code after an object is put into collect.
Highlights of this section:
● To detect the equality of objects, provide the "isequal:" And hash methods.
● The same object must have the same hash code, but the two objects with the same hash code may not be the same.
● Do not blindly inspect each attribute one by one. Instead, you should customize the detection scheme based on specific requirements.
● When writing a hash method, you should use an algorithm that is fast in computing and has a low probability of hash code collision.
Article 3: Hide implementation details in the class family mode
The class cluster mode is a very useful pattern that hides the implementation details behind the abstract base class. This mode is widely used in objective-C system frameworks. For example, there is a uibutton class in the IOS user interface framework uikit.
Article 3: using Correlated objects in existing classes to store Custom Data
Directly list common examples in development: Use of A uialertview. The common practice is as follows:
-(void) askUserAQuestion{ UIAlterView *alert = [[UIAlterView alloc] initWithTitle:@"Question" message:@"what do you want to do?" delegate:self cancelButtonTitle:@"cancel" otherButtonTitle:@"cancel",nil]; [alert show];}//UIAlertViewDelegate protocol method-(void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ if(buttonIndex == 0){ [self doCancel]; } else { [self doContinue]; }}
Alertview creation and processing are not in the same place. During the development process, the code is often slide back and forth to view. Then the "associated object" plays a role and associates the operation with the uialertview. For example:
static void* EOCMyAlertKey = "EOCMyAlertViewKey";-(void) askUserAQuestion{ UIAlterView *alert = [[UIAlterView alloc] initWithTitle:@"Question" message:@"what do you want to do?" delegate:self cancelButtonTitle:@"cancel" otherButtonTitle:@"cancel",nil]; void (^block)(NSInteger) = ^(NSInteger buttonIndex){ if(buttonIndex == 0){ [self doCancel]; } else { [self doContinue]; } }; objc_setAssociatedObject(alert,EOCMyAlertViewKey,block,OBJC_ASSOCIATION_COPY); [alert show];}//UIAlertViewDelegate protocol method-(void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ if(buttonIndex == 0){ [self doCancel]; } else { [self doContinue]; }}-(void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ void (^block)(NSInteger) = objc_getAssociatedObject(alertView,EOCMyAlertViewkey); block(buttonIndex);}
Introduce the techniques used to improve the Code
● void objc_setAssociatedObject(id object, void*key ,id value,objc_AssociatedPolicy policy)
This method sets the associated object value for an object based on the given key and policy.
● id objc_getAssociatedObject(id object,void* key)
This method obtains the associated object value from an object based on the given key.
● void objc_removeAssociatedObjects(id object);
Yesobject association type
However, this method should be used with caution. When using block, be careful to reference it cyclically (refer to the introduction of bloc ). So the general practice is: Inherit the subclass from it and save the block as the attribute in the subclass.