The conventions of iOS development (1) ———— "52 Effective ways to write high-quality iOS and OS X code" reading notes (chapter I) preface
"I want to be a productive developer. "If you want to mix well, you have to work harder." ”
Write these things because after all, read the book, but after reading the past, perhaps the impression is not very deep, and some things can not understand now, then I will understand, now it is possible to use the things, simple to write to the good, so that they can see in the future to understand the meaning of the.
There is the exercise of expression, editing ability, slowly improve their own, anytime and anywhere to have a training heart.
Finally, of course, to share with you, it is also necessary for us to discuss the discussion together.
Welcome everyone to criticize the advice!
Minimize references to other header files in the header file of the class
- The main purpose is to avoid two classes of mutual calls resulting in compilation errors, especially when two classes declare the protocol method, perhaps there is no direct mutual invocation (interdependence) situation, but if the third file caused by the mutual invocation of the error, it is very happy to find a very laborious.
- To prevent this, generally try to use the @class keyword for processing, and pay attention to the statement of the Protocol agent.
- For the method of definition of the protocol, we can define the protocol to a separate. h file, of course, there may be other circumstances, but in the circumstances I see this is the case, if there are other circumstances, and so I know later.
- There is a mutual call to the header file will lead to the increase in compilation time, perhaps this is our novice programmer writing programs less efficient than the reason of the veteran.
Use more literal syntax and less of the equivalent method
- What is literal syntax is that when defining such objects as nsarray,nsdictionary,nsstring,nsnumber, some of the simpler methods are used, as follows: the definition of the variable name suffix "1" is the traditional definition method, of course, there are corresponding class methods, I didn't write here. The literal syntax is the variable name suffix "2".
nsdictionary*dict1 = [[nsdictionaryAlloc] initwithobjectsandkeys:@"Object", @"Key",Nil];nsdictionary*dict2 = @{@"Key": @"Object"};Nsarray*array1 = [[NsarrayAlloc] initwithobjects:@"Object",Nil];Nsarray*array2 = @[@"Object1",@"Object2",@"Object1"];NSString*string1 = [[NSStringAlloc] initwithstring:@"string"];NSString*string2 = @"string";NSNumber*number1 = [[NSNumberAlloc] Initwithint:1];NSNumber*number2 = @1;
Where Nsarray,nsdictionary also has a corresponding value operation:
NSString *value1 = [dict1 objectForKey:@"key"]; NSString *value2 = dict2[@"key"]; NSString *str1 = [array1 objectAtIndex:1]; NSString *str2 = array2[1];
There are two key benefits to using literal syntax:
- The code is more concise and understandable, objective-c we all understand, so using this syntax can effectively make our code easier to read, easy to maintain.
- It is also important to use the traditional Alloc method or class method, if you want to put three elements in the array, when the second element is nil, the compiler will not have any exception, will only create an array of only the first element, The result is that your program is not running the way you want it to, and you may not be able to find it in time when you compile the test, so it will be more troublesome.
But of course when you use literal syntax, the compiler throws a similar:
? The exception of the. So I think it can be found and processed in time.
Variables created using the literal syntax are immutable, and we need to copy them at this point:
NSMutableArray *array3 = [array2 mutableCopy];
Multi-use type constants, less # define preprocessing directives
In the development process, we might do this when we need to fix a constant, such as when we play the animation, and when we send the name parameter of the notification:
#define ANIMATION_DURATION 0.3#define kPushNotificationName @"pushNotificationName"
However, there are several problems with preprocessing directives:
- The defined constants do not have type information, the name of the constant may not explicitly indicate the type of the constant, and in the compilation process, the compiler will all "animation_duration" is replaced by 0.3, so that the addition of other problems referred to the header file, it will be all the The "Animation_duration" is replaced.
- And using this method, there is no guarantee that the value of the instruction will not change during the program's operation.
So for this scenario, we can define it in the following way:
staticconstNSTimeInterval0.3;
- A variable uses the static adornment to ensure that the variable is visible only in the compilation unit that defines the variable. A static variable modifier that guarantees that the variable will not be released until the edit unit (similar to Viewcontroller) is released, and does not reopen the address space each time.
- Variables that use the const modifier can guarantee that the variable will not change, and the compiler will error when attempting to modify the const-modified variable.
- When a variable is declared as static and declared as const, the compiler does not create a symbol at all, but instead replaces all encountered variables with a constant value, just like #define preprocessing directives.
- However, this method is defined with type information.
In general, variables that are directly defined using this method are typically used in an implementation file (. m file), that is, the current file is available, and try not to define it in the header file (. h file). So similar to the name parameter used in nsnotification definition, the constant used to tag the notification name is not very suitable to be defined directly in such a way, because generally nsnotification we need to post (send a notification), Addobserver ( Add a notification to receive) all use the name constant, and it may be necessary to use the constant in many places, then we need to use the following method:
//. h file #import <FOUNDATION/FOUNDATION.H> @interface loginmanager : nsobject extern NSString *const loginmanagerpushnotification; @end
// .m 文件中#import "LoginManager.h"NSString *const loginManagerPushNotification = @"LoginManagerPushNotification";@implementation LoginManager@end
- Use this method to declare an externally visible constant variable so that the registrant does not need to know the actual string value, just register the notification you want to accept with a constant variable.
- The keyword extern, which tells the editor that there will be a symbol called "loginmanagerpushnotification" in the global symbol table, that is, the compiler does not need to look at its definition, which allows the code to use that constant. Because it knows that when linked to a binary file, this constant can certainly be found.
Finally, let's say that we should try to avoid using #define preprocessor directives, rather than using #define preprocessor directives, for some constants like this:
//size of screen#define kscreenbounds ([[[UIScreen mainscreen] bounds])#define kscreenwidth (kScreenBounds.size.width)#define kscreenheight (kScreenBounds.size.height)//generate the corresponding color#define Luicolorfromrgb (rgbvalue) [Uicolor \Colorwithred: ((float) ((Rgbvalue &0xFF0000) >> -))/255.0Green: ((float) ((Rgbvalue &0xff00) >>8))/255.0Blue: ((float) (Rgbvalue &0xFF))/255.0Alpha1.0]//System version judgment#define ksysver ([[[[[Uidevice Currentdevice] systemversion] floatvalue])#define ios9later (ksysver >= 9.0f)#define ios8later (ksysver >= 8.0f)#define ios7later (ksysver >= 7.0f)#define ios6later (ksysver >= 6.0f)#define iOS7 (ksysver >= 7.0f && ksysver < 8.0f)//System Current language#define llanguages [[Nslocale preferredlanguages] objectatindex:0]
We can still use it.
Flag State, option, state with enumeration
Because Objective-c is based on C, he has all the features of C. One of them is enum type: enum. When you represent error status codes or Composable options in a series of constants, it is advisable to use enumerations to name them. I'm not going to say much about the syntax of enumerations.
Generally the simplest usage is:
typedefenumNSInteger { MessageUpdateSuccess, MessageUpdateFailed} MessageUpdateStatus;
Of course we can also make the underlying data type, just like this:
typedefenumNSInteger { 1, MessageUpdateFailed,} MessageUpdateStatus;
As far as I am concerned, the above two usages have already met my needs, but there is a situation like this, I now understand is not very clear, let's put it out for everyone to see it.
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5};
In addition, the system defines some auxiliary macros, which are used to specify the underlying data type that holds the enumeration values. I still do not understand this, it may be a relationship that has not been used so far, I will not say here.
The conventions of iOS development (1) ———— "52 Effective ways to write high-quality iOS and OS X code" reading notes (chapter I)