Level: ★☆☆ Tag: NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE Specifies the initialization method for iOS by WYW


Introduction: The author recently learned some content related to SDK development, and encountered some problems when it came to the initialization method of specifying view controller (hereinafter referred to as VC for view controller). Here I share with you the setting method, if you have different opinions, please advise.

The author encountered the following problems:

I want businesses using the SDK to initialize VC using the methods identified in the SDK. The following author needs to pass in the VC navigation bar title and initialize the corresponding VC as an example to clarify the relevant problems. For the above situation, there are several ways to deal with it, such as:

  1. In the header file exposed by the SDK, the text says which initialization method to use; Specify in the documentation which initialization method to use; Include appropriate sample code in the provided Demo.
  2. The vc initialization method is specified using the NS_DESIGNATED_INITIALIZER macro given by the system

The section specifying the initialization method can be specified using the macro NS_DESIGNATED_INITIALIZER, so if the business does not look at the SDK header file and directly specifies the initialization method by using new or alloc init, then the navigation bar title we need to initialize VC will not be passed in properly.

In this case, we can offer the following three methods:

  1. Use the system macro NS_UNAVAILABLE to set initialization methods that you do not want your business to be using as unavailable. For example, if new is disabled, the effect will be: if the business wants to use new to initialize VC, it will find an error message, using this method is relatively easy.
  1. For initialization methods that do not want to be used by business, implement them in the implementation file and give them default values. For example, in the case of initializing the VC navigation bar title, the given default title is defaultNavigationTitle. However, this method of initialization is not suitable for passing in important parameters, otherwise the business will feel strange. In addition, in this way, if there are related changes in the future, the code may be changed more.
  1. For the initialization method that the business does not want to use, in the implementation file, implement the corresponding method, and throw a crash, and specify the crash cause, in the crash cause should be used to initialize VC method. For this approach, if there are changes to be made later, the code may be changed a lot.

I prefer the first approach to the other three. If you have other ideas, please discuss them.

Below we still initialize VC, specify the incoming navigation bar title as an example, pasted the relevant example code.

The first way:

//.h file - (instancetype)initWithSomething:(id)someThing NS_DESIGNATED_INITIALIZER; - (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil bundle:(nullable NSBundle *)nibBundleOrNil NS_UNAVAILABLE; - (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; - (instancetype)init NS_UNAVAILABLE; + (instancetype)new NS_UNAVAILABLE;Copy the code
//.m file /*! @brief title */ @property (nonatomic, copy) NSString *navTitle; - (instancetype)initWithSomething:(id)someThing { // Cannot assign to 'self' outside of a method in the init family // Specifying the initialization method must start with 1. init. 2. And init next to init is capital self = [super initWithNibName:nil bundle:nil]; if (! self) { return nil; } _navTitle = someThing; [self commonInit]; return self; } - (void)commonInit { self.navigationItem.title = _navTitle; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; }Copy the code

The second way:

.h
- (instancetype)initWithSomething:(id)someThing;

Copy the code
//.m file /*! @brief title */ @property (nonatomic, copy) NSString *navTitle; - (instancetype)initWithSomething:(id)someThing { self = [super init]; if (! self) { return nil; } _navTitle = someThing; return self; } - (instancetype)init { self = [super init]; if (! self) { return nil; } [self commonInit]; return self; } - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (! self) { return nil; } [self commonInit]; return self; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (! self) { return nil; } [self commonInit]; return self; } - (void)commonInit { _navTitle = @"Default"; } - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = _navTitle; self.view.backgroundColor = [UIColor whiteColor]; }Copy the code

The third way:

//.h file - (instancetype)initWithSomething:(id)someThing;Copy the code
//.m file static NSString *const kExceptionName = @" initialization error "; Static NSString *const kExceptionReason = @" Please use initWithSomething: to initialize "; / *! @brief title */ @property (nonatomic, copy) NSString *navTitle; - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = _navTitle; self.view.backgroundColor = [UIColor whiteColor]; } + (instancetype)new { @throw [[self class] initExceptioin]; return nil; } - (instancetype)init { @throw [[self class] initExceptioin]; return nil; } - (instancetype)initWithCoder:(NSCoder *)aDecoder { @throw [[self class] initExceptioin]; return nil; } - (instancetype)initWithSomething:(id)someThing { self = [super init]; if (! self) { return nil; } _navTitle = someThing; return self; } + (NSException *)initExceptioin { return [NSException exceptionWithName:kExceptionName reason:kExceptionReason userInfo:nil]; }Copy the code

The Demo:

Demo: QiDesignatedInitializer

Refer to study website

  • IOS specifies the initialization method

  • IOS specifies the correct use posture of the initialization method

  • Effective Objective-C 2.0:52 Effective Ways to write High quality iOS and OS X code


Recommended articles:

UIView hitTest method iOS notes on tabBar A’s daughter is the mother of B’s daughter, who is A of B? IOS Runloop (a) iOS common debugging method: LLDB command iOS common debugging method: breakpoint iOS common debugging method: Static analysis strange dance weekly