Make the code a little more handsome

Source: Internet
Author: User

Blogger's Private blog

The most important thing to write code is to implement the function, but in addition to the implementation of functionality, we should also find ways to make the code more standardized, more beautiful
Recently reading "Zen and OBJECTIVE-C Programming art" and "Effective Objective C 2.0:52 Effective ways to write high-quality iOS and OS X code", both of which explained code specifications, combined with their usual code habits, Found that there are many places to do their own is not good enough, the code is not handsome enough to write, so summarize, let the later code more handsome

Conditional statements

Conditional statements must use parentheses, and if you do not use parentheses, the next line of code will be deleted, and the code that follows would be the code inside the IF statement
Recommended:

if (!error) {    return success;}
Brackets

Use of curly braces is best consistent with Apple, curly braces start on the same line, end in a new line,
Such as:

if (user.isHappy) {    //Do something}else {    //Do something else}
Nil and bool Judgments

It is best ! to use judgment directly nil , or bool value
Recommended:

if (![someObject boolValue]) { ...if (!someObject) { ...
Avoid nesting if

Do not nest if statements. Using multiple return avoids increasing the complexity of loops and improving the readability of your code.
Recommended:

- (void)someMethod {  if (![someOther boolValue]) {      return;  }  //Do something important}

Not recommended:

- (void)someMethod {  if ([someOther boolValue]) {    //Do something important  }}
Multi-use literal syntax

What is literal syntax

NSString *string = @"string";NSNumber *intNumber = @88;NSNumber *boolNumber = @YES;NSNumber *floatNumber = @3.14;int var = 3;NSNumber *varNumber = @(var);NSArray *list = @[@"itme1",@"item2",@"item3"];NSLog(@"%@,%@,%@",list[0],list[1],list[2]);NSDictionary *map = @{@"key1":@"value1",@"key2":@"value2"};NSLog(@"%@,%@",map[@"key1"],map[@"key2"]);

This is the literal syntax, a very simple and intuitive way to create or get common objects (nsstring,nsnumber,nsarray,nsdictionary), using literal syntax simple and intuitive

Complex expressions

When there is a complex if statement, the judging condition can be extracted as a bool variable

BOOL nameContainsSwift  = [sessionName containsString:@"Swift"];BOOL isCurrentYear      = [sessionDateCompontents year] == 2014;BOOL isSwiftSession     = nameContainsSwift && isCurrentYear;if (isSwiftSession) {    // Do something very cool}
Use constants instead of macros

Recommended:

static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";static const NSTimeInterval animationDuration = 3.0;

Not recommended:

#define ZOCCacheControllerDidClearCacheNotification @"ZOCCacheControllerDidClearCacheNotification"#define animationDuration 3.0

Reason:
1. The constant type is not directly known in the process of using a macro (is it an int?). Or the stiring? ), unless you see where the macro is defined
2. Macros can be changed, if 2 places use the same name to define 2 different macros, you can use the error, causing difficult to find bugs. Constants defined with const if you change the compiler, you will get an error.

Static

In the use of constants in the process of two kinds of situations
1. Constants require external exposure. Not used static and exposed in. h extern

// .hextern NSString *const ZOCCacheControllerDidClearCacheNotification;// .mNSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";

2. Constants are used only in this class and do not need to be exposed to external use static .

static NSString * const ZOCCacheControllerDidClearCacheNotification = @"ZOCCacheControllerDidClearCacheNotification";

staticThe defined variables are only visible in the current. m file, and if the constants are used only in this class, they static will avoid affecting other classes and cannot be used if global visibility is required.static

Class naming conflicts

1) class name, global variable and C function (c function similar to global variable) when naming, use three letters as prefix, avoid naming conflict with third-party API or Apple API name
It is often seen in projects that you do not use a prefix or use two letters as a prefix for naming.
The possibility of conflict without using a prefix is self-evident, so why not use two letters as a prefix?
Because Apple claims it retains the right to use all the "two-letter prefixes", using a two-letter prefix has the risk of conflict with the future Apple API, so be on the safe side, use three letters as the name prefix for iOS

2) Private methods used inside the class can be prefixed, but not prefixed with a single underscore _ , because this is also reserved by Apple. Double underline __ or prefix can be p_ used

3) If you need to add a category to a non-source class (including third-party classes and system classes), it is best to prefix the method name to avoid conflicts

Designated Initializer

Subclasses should follow these steps when redefining designated initializer:

    1. Define designated initializer, and call the designated of the parent class initializer
    2. Overloads the parent class's designated initializer and invokes the newly defined designated initializer
    3. Write a document for the new designated initializer

In. h, use to __attribute__((objc_designated_initializer)) indicate which is the designated initializer.
If for some reason the parent class's designated initializer is deprecated, such as designated initializer must have a parameter, the designated initializer of the parent class cannot pass this argument. __attribute__((unavailable("Invoke the designated initializer")))Deprecated with presentation

- (instancetype)initWithName:(NSString *)name __attribute__((objc_designated_initializer));- (instancetype)init __attribute__((unavailable("Invoke -initWithName:")));
Encapsulation of classes

When encapsulating a class, here are a few things to note:

    1. Properties and methods that are not required to be understood externally, as far as possible in. m
    2. Do not easily expose property setter methods, use readonly more
    3. Use immutable objects as much as possible
    4. Do not expose the variable collection, should provide the corresponding method substitution
Protocol

1) generally protocol divided into 2 categories, delegate and DataSource

    1. Delegate: Entrust other class to work, need to put in delegate inside, generally no return value
    2. DataSource: To get data from another class, put it in dataSource and use it for data acquisition.

2) delegate attribute under Arc, be sure to replace assign with weak, avoid hidden trouble
3) for option protocol. Make sure -respondsToSelector: that this method is implemented before calling it.

Property specification

Attributes are best written in terms of code specification and beauty, which is what Apple is writing
Recommended:

Not recommended:

@property(nonatomic, readonly, copy) NSString* nibName; @property(nonatomic, readonly, copy)NSString *nibName; @property (nonatomic, readonly, copy) NSString *nibName; ...
Setter&getter

Properties in addition to Init and dealloc, it is recommended to use setter and getter methods. In Init and dealloc, it is recommended to use Ivar directly
Benefits of using setter and getter methods:

    1. Adhere to memory management semantics (strong,copy ...)
    2. KVO notification will be executed automatically
    3. Easy Debug, break point
    4. Easy to rewrite getter or setter

Why not use setter and getter in Init and dealloc?
If the setter is used in Init, the setter method is called when the "Super Init" is called before the properties of the child class are initialized. At this point, if you rewrite the setter and do a special operation in the setter, this can cause some very difficult to find bugs. So to avoid the pitfalls, use Ivar directly in Init or dealloc

Variable Object Assignment

For properties that can be assigned a value with a mutable object (for example: Nsstring,nsarray,nsdictionary), the memory management type of the property must be copy . This is to prevent mutable objects (Nsmultablearray) from assigning values to immutable objects (Nsarray). Causes the Immutable object (nsarray) pointer to point to a mutable object (Nsmultablearray), which may change its value during use, and a bug occurs

Dot symbol

When using attributes, use symbols as much as possible . , and method calls use [] the
Cases:

 view.backgroundColor = [UIColor orangeColor];[UIApplication sharedApplication].delegate;
Block

Recommend this block use method

__weak __typeof(self)weakSelf = self;[self executeBlock:^(NSData *data, NSError *error) {    __strong __typeof(weakSelf) strongSelf = weakSelf;    if (strongSelf) {        [strongSelf doSomethingWithData:data];        [strongSelf doSomethingWithData:data];    }}];

Hold self with weak outside block, avoid circular references
In block with strong hold self, avoid multi-threaded block execution half, self is released to nil, and the hidden danger
Other block issues, you can see the previous writing of this article

mutable collections never enumerate mutable collections

Recommended:

NSArray *staticArray = [multableArray copy];for (id item in staticArray) {    ....}

Not recommended:

for (id item in multableArray) {    ....}

A mutable collection can cause crash if it changes at enumeration time.
Never enumerate mutable collections, no matter how sure you are that the collection will not change. Because the code may be modified later, there may be other threads that will change the collection, too many surprises may occur, and the only guarantee that there will be no surprises is never to enumerate the mutable collections

Do not expose mutable collections to public properties

Recommended:

// .h@property(nonatomic, readonly) NSArray *staticArray;// .m@property(nonatomic, strong) NSMutableArray *mutableArray;- (NSArray *)staticArray{    return [self.mutableArray copy];}

① Not recommended:

// .h@property(nonatomic, readonly)NSMutableArray *mutableArray;

② Not recommended:

// .h@property(nonatomic, readonly) NSArray *staticArray;// .m@property(nonatomic, strong) NSMutableArray *mutableArray;- (NSArray *)staticArray{    return self.mutableArray;}

You never know what you're going to do with this mutablearray outside, assuming that this mutablearray is being enumerated outside, and that the other threads Mutablearray changed. Bang, crash, not the completion, but also the rhythm of overtime ...

If you need to change the item in this array externally, add a method to change the item:

// .h@property(nonatomic, readonly) NSArray *staticArray;- (void)addItem:(id)item;- (void)removeItem:(id)item;//.m@property(nonatomic, strong) NSMutableArray *mutableArray;- (void)addItem:(id)item{    [self.mutableArray addObject:item];}- (void)removeItem:(id)item{    [self.mutableArray removeObject:item];}
Nsnotificationremove

Notification must be remove!.
Notification must be remove!!.
Notification must be remove!!!.
Important things must say three times, notification not remove is easy to crash, including KVO, also must remember remove, otherwise there will be crash in front of you ...

Multiple registrations

Notification if multiple registrations will result in a post, the method is called several times, so pay attention to the registration notice must see clearly, whether the notification is registered only once, it is recommended to register in the init notice, dealloc in the Remove notice

Reference

The art of Zen and OBJECTIVE-C programming
Effective Objective C 2.0:52 Effective ways to write high-quality iOS and OS X code
How does not to Crash

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Make the code a little more handsome

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.