@(iOS development learning)

Objective-c Basic Routines

Objective-c details

The specified constructor and the convenient initialization method in Swift

  • 3.1. Why initialization?

  • 3.2 Several methods of class initialization

    • 3.2.1, Designated
    • 3.2.2, convenience,
    • 3.2.3, required

Objective-c Basic Routines

Problems encountered in daily development:

In normal project development, it is common to encounter multiple people developing a requirement at the same time. Colleague provides A custom initialization method, but the colleague B invokes the default initialization method, because the colleagues in A custom initialization method to some special operation, cause the colleague B use the default initialization method did not achieve the desired effect, and then waste A lot of effort to communicate to find A problem with my colleagues.


Most programmers work on projects with other members of the team, and even if they’re working on a project independently, one module calls another, they need a clear interface specification. When faced with multiple initialization methods, external callers may not know which one is the correct one. For this, Apple provides two keywords: NS_UNAVAILABLE and NS_DESIGNATED_INITIALIZER to help us constrain the object’s initialization method and make the interface description clearer.

  • NS_DESIGNATED_INITIALIZER: Used to mark the decorated method as the specified constructor

  • NS_UNAVAILABLE: Disables the use of an initialization method

It is generally expected that when an external interface is called, some basic parameters are passed in for initialization. Instead of using the default initialization method, we can do this:

@interface Person : NSObject
@property (nonatomic.strong) NSString *name;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithName:(NSString*)name NS_DESIGNATED_INITIALIZER;
@end

@implementation Person
- (instancetype)initWithName:(NSString *)name {
    if ( self = [super init] ) {
        self.name = name;
    }
    return self;
}
@end
Copy the code

When creating a Person object, you cannot use the [Person New] and [[Person Alloc]init] methods of NS_UNAVAILABLE modifications, Instead, use the – (instancetype)initWithName:(NSString*)name method decorated with NS_DESIGNATED_INITIALIZER.

// Xcode is reporting an error: 'new' is unavailable
Person* person1 = [Person new];
// Xcode is reporting an error: 'init' is unavailable
Person* person2 = [[Person alloc]init];
/ / right
Person* person3 = [[Person alloc]initWithName:@"XiaoMing"];
Copy the code

Objective-c details

When you want the caller to call its own constructor, you can decorate it with NS_DESIGNATED_INITIALIZER in the. H file


When you don’t want the caller to call the constructor of the parent class, you can use the NS_UNAVAILABLE modifier in the.h file


If a subclass implements the specified initialization method of the NS_DESIGNATED_INITIALIZER modifier, no NS_UNAVAILABLE modifier is used to modify the parent class’s initialization method. Override the parent class’s designated initializer in the subclass and call the subclass’s own designated initializer in the subclass. Because if a class’s method is decorated with NS_DESIGNATED_INITIALIZED, the modified method becomes the specified constructor, and the specified constructor inherited from the parent class becomes the convenient initialization method. A subclass that does not override its parent’s specified initializer raises a similar warning:

1, ⚠️ : Method override for the Designated Initializer of the superclass ‘-init’ not found

2. ⚠️ : Convenience initializer missing a ‘self’ call to another initializer

Super-related methods cannot be called after overriding the specified initialization method of the parent class. Otherwise, a similar warning will be reported:

⚠️ : Convenience initializer should not invoke an initializer on ‘super’ (Convenience initializer method cannot call super initializer method)


Avoid using new to create objects. From a security and design point of view, we should initialize all properties to improve the robustness and reuse of the program.

In either case, it is good programming practice to include at least one constructor in a class, and if a class has attributes, it is often good practice to initialize those attributes. — From The Object-oriented Thought Process by Matt Weisfeld


Terminology: constructor vs. initializer

There’s no constructors in Objective-C strictly, all we’re talking about are initializers, you create an object (alloc) and then you call the instance’s initializer, initWithXXX.

Constructor: class name (argument list…)

A constructor is a special type of method that has the same name as a class and returns a value of the same class type. Object creation is accomplished through the constructor, whose function is mainly to complete the initialization of the object. The constructor is automatically called when a class instantiates an object. Constructors can be overloaded just like any other method.


The difference between objective-C and Swift initialization order:

Objective-c first calls the parent class’s initialization method and then initializes its own member variables

Swift initializes its own member variables and then calls the parent class’s initialization method

The specified constructor and the convenient initialization method in Swift

class People { var name: String? // In Swift, attributes that are not of an optional type must be initialized. Var age: Intinit() {age = 0} String) { self.init() self.name = name } } class Man: People { var mustacheLength: Int // Subclasses override the specified initialization method of their parent class. Override is required to modify Overrideinit() {self.mustachelength = 0} Int) {self.init() self.mustachelength = mustacheLength // Change the value of the parent class property only after calling the specified initialization method inside the convenience initialization method of the subclass. Self.age = 1} // Convenience init(mustacheLength: Int, name: String =) convenience init(mustacheLength: Int, name: String ="") {
        self.init(mustacheLength: mustacheLength)
    }
}
Copy the code

3.1. Why initialization?

  • The storage properties must be initialized
  • The structure system adds initialization methods by default, but you can also customize them

3.2 Several methods of class initialization

3.2.1, Designated

  • Optional values do not need to be initialized. If the value is not initialized, the system uses it by defaultnilInitialize it.
  • If a class has a non-optional storage property and no default value, you must implement the specified initialization method and initialize the property.
  • If a subclass does not have its own initialization method, the system uses the initialization method of the parent class by default. Once the subclass has its own initialization method or overrides the initialization method of the parent class, all initialization of the parent class cannot be called by the subclass.
  • You can add the same initialization methods to subclasses as the parent class, but you need tooverrideModification.

3.2.2, convenience,

  • In the same class, useconvenienceThe decorated initializer must call another initializer.
  • convenienceA specified initialization method must eventually be called.
  • Overrides the parent classconvenienceA convenient initialization method modified without addingoverrideThe keyword.

3.2.3, required

  • A subclass must override its parent classrequiredMethod of decoration
  • Can be used in combination with convenience

The resources

NS_UNAVAILABLE and NS_DESIGNATED_INITIALIZER

Swift Initialization

Swift-init Initialization method