15th: Avoid namespace collisions with prefixes
Objective-c has no other language built-in namespace (namespace) mechanism. The following error occurs when a naming conflict program connection occurs:
Duplicate symbol _objc_metaclass_$_eoctheclass in:
Build/something.o
Build/something_else.o
Duplicate symbol _objc_class_$_eoctheclass in:
Build/something.o
Build/something_else.o
The reason for the error is that two of the code in the application implements the Eoctheclass class. The only way to avoid this problem is to disguise the namespace.
When creating an application using cocoa, it is important to note that Apple claims that it retains all "two-letter prefixes", so you should choose three or more prefixes yourself.
16th: Provide "All-in-one initialization method" 17th: When implementing the Description method debugger, you often need to print and view object information. One way to do this is to write code that prints all the properties of the object to the log. However, the most common practice is as follows:
NSLog (@ "Object =%@", object);
If object is Nsarray then all the contents of the array are printed, and if object is a custom class object, then the result is a memory address. Unless you overwrite the description method in your own class. Exactly what fields to print are written as needed. There is another way to note in the NSObject protocol is that debugdescription, which is used for debugging output. For example: We enter the PO command in the console, output:eoctest[640:c07] person = <eocperson:ox712ad0, "Bob Smith" >Note that the console console "(eocperson*) $1=0x712a4d0" is added by the debugger, and the following content is the information returned by Debugdescription, You can override the Debugdescription method if you need to print more information about the custom class when debugging
18th: When possible to use immutable object design class, should fully use attributes to encapsulate the data. When you use a property, you can declare it as read-only (read-only). By default, properties are "both readable and writable" as far as possible to create immutable objects if an attribute can only be modified inside an object, expand it from the ReadOnly property to the ReadWrite property in the Class-continuation category Instead of exposing mutable collection as attributes, you should provide a method to modify the variable collection in the object at once.
19th: The use of a clear and coordinated naming method NSString This class shows a good naming habit.
● +string / / used to create a new empty string
● +stringWithString / / factory method for creating a new string based on a string
● +localizedStringWithFormat:// factory method, format local string
● -lowercaseString// convert all uppercase letters in the string to lowercase
● -intValue// resolves a string to an integer
● -length//Get the length of the string
● -lengthOfBytesUsingEncoding://If the string is in the given encoding format
● -getCharacters: range://gets the string of the given range of characters
● -(void)getCharacters:(unichar*)buffer range:(NSRange)aRange//The first argument should point to a large enough array to accommodate those strings within the request scope.
● -hasPrefix:// Is there a prefix?
● -isEqualToString://Check if the strings are equal
20th: Prefix The private method name 21st: Understanding the OBJECTIVE-C Error model the Nserror object encapsulates three messages: the range of error domain (Error range, string) errors occur. That is, the root cause of the error, usually defined by a unique global variable. For example, "Subsystem handling URLs", when parsing fetched data from a URL, uses Nsurlerroedomain to represent the error range if something goes wrong. Err code (error code, int) User info (user information, dictionary) in the case of a less serious error, you can either assign a "delegate method" to handle the error, or you can put the error message into the Nserror object, and return it to the caller via an "output parameter". 22nd: Understand that the Nscopying protocol uses objects often need to copy it. In Objective-c, this is done through the copy method. If you want to enable your class to support copy operations, then implement the Nscopying protocol, which has only one method:
-(ID) Copywithzone: (nszone*) zone
Why do Nszone appear? Since the program was developed in the past, the object would be created in some way, based on the partitioning of the memory into a different "zone" (Zone). Not now, there is only one zone per program: "Default Zone". So, despite the implementation of this method, you don't have to worry about the zone parameters
#import<Foundation/Foundation.h>
@interface EOCPerson :NSObject<NSCopying>
@propetry (nonatomic,copy,readonly) NSString *firstName;
@propetry (nonatomic,copy,readonly) NSString *lastName;
-(id) initWithFirstName:(NSString*)firstName andLastName:(NSString*)lastName;
-(void)addFriend:(EOCPerson*) person;
-(void)removeFriend:(EOCPerson*)person;
@end
@implementation EOCPerson{
NSMutableSet *_friends;
}
-(id) initWithFirstName:(NSString*)firstName andLastName:(NSString*)lastName{
if((self = [super init])){
_firstName = [firstName copy];
_lastName = [lastName copy];
_friends = [NSMutableSet new];
}
return self
}
-(void)addFriend:(EOCPerson*)person{
[_friends addObject:person];
}
-(void) removeFriend:(EOCPerson*)person{
[_friends removeObject:person];
}
-(id)copyWithZone:(NSZone)zone{
EOCPerson *copy =[[[self class]allocWithZone:zone] initWithFirstName:_firstName andLastName:_lastName];
copy->_friends = [_friends mutableCopy];
return copy
}
@end
The Copywithzone achieves 1. Copy a copy of the eocperson,2. It copies a copy of the local _friends instance variable, which points to the copied set by the _friends instance variable of the Copy object.Note that the syntax used hereBecause _friends is not a property. If _friends is an immutable array, you do not need to copy one. When writing a copy method, it is also a matter of deciding whether to "deep copy" or "Shallow copy". A deep copy means that the underlying data is copied as well when the object itself is copied. All collection classes in the foundation framework perform money copies by default, that is, only the container object itself is copied, not the data in it. For container classes
In Nsset, for example, this class provides the following initialization method to perform a deep copy
-(ID) Initwithset: (nsarray*) array Copyitems: (BOOL) Copyitems
Because there are no protocols that specifically define deep copies, their implementation is determined by each class, and you only need to decide if the class you are writing is going to provide a deep copy method. For copy of non-container class, take nsstring as an example
// non-container class object
NSString *str = @"origin string";
NSString *strCopy = [str copy];
NSMutableString *mstrCopy = [str mutableCopy];
[mstrCopy appendString:@"??"];
STR and strcopy point to the same piece of memory (a shallow copy), which we call a weak reference (weak reference). And mstrcopy is the real copy (deep copy)
NSMutableString *mstr = [NSMutableString stringWithString:@"origin"];
NSString *strCopy = [mstr copy];
NSMutableString *mstrCopy = [mstr copy];
NSMutableString *mstrMCopy = [mstr mutableCopy];
//[mstrCopy appendString:@"1111"]; //error
[mstr appendString:@"222"];
[mstrMCopy appendString:@"333"];
The memory allocated by the above four objects is not the same. And for Mstrcopy, it's actually a imutable object, it's immutable, so it's going to go wrong. Pay attention to this point and understand it well.
For non-container class objects, there are:
If copying an immutable object, copy is a pointer copy, which is a shallow copy, whereas mutablecopy is an object copy, or deep copy.
If it is a copy of a mutable object, it is a deep copy, but the object returned by copy copy is immutable.
"Main points of this chapter"
You need to implement the Nscopying protocol if you want to write objects that have copy functionality. If a custom object is divided into a mutable version and an immutable version, then both the nscopying and nsmutablecopying protocols are implemented. When copying objects, you need to decide whether to use a shallow copy or a deep copy to perform a shallow copy as much as possible. If you are writing objects that require a deep copy, consider adding a new method that specifically performs deep copies.