构造方法

1.重写init方法

  • 想在对象创建完毕后,成员变量马上就有一些默认的值就可以重写init方法

  • 重写init方法格式:

- (id)init {
    self = [super init];
    if (self) {
        // Initialize self.
    }
    return self;
}
  • + [super init]的作用:

  面向对象的体现,先利用父类的init方法为子类实例的父类部分属性初始化。

  • + self 为什么要赋值为[super init]:

简单来说是为了防止父类的初始化方法release掉了self指向的空间并重新alloc了一块空间。还有[super init]可能alloc失败,这时就不再执行if中的语句。

  • 重写init方法其它格式
- (id)init {
    if (self = [super init]) {
        // Initialize self.
    }
    return self;
}

2.练习

  • 要求通过Person类创建出来的人初始化值都是10岁。
@implementation Person

- (instancetype)init
{
    if (self = [super init]) {
        _age = 10;
    }
    return self;
}
@end
  • 让学生继承人类,要求学生对象初始化之后,年龄是10,学号是1,怎么办?
@implementation Person

- (instancetype)init
{
    if (self = [super init]) {
        _age = 10;
    }
    return self;
}
@end

@implementation Student

- (instancetype)init
{
    if (self = [super init]) {
        _no = 1;
    }
    return self;
}
@end

3.构造方法使用注意

  • 子类拥有的成员变量包括自己的成员变量以及从父类继承而来的成员变量,在重写构造方法的时候应该首先对从父类继承而来的成员变量先进行初始化。
    • 原则:先初始化父类的,再初始化子类的。
      • 先调用父类的构造方法[super init];
      • 再进行子类内部成员变量的初始化。
  • 千万不要把self = [super init]写成self == [super init]

  • 重写构造方法的目的:为了让对象方法一创建出来,成员变量就会有一些固定的值。

4.instancetype的作用

  • instancetype与id相似,不过instancetype只能作为方法返回值,它会进行类型检查,如果创建出来的对象,赋值了不相干的对象就会有一个警告信息,防止出错。
// init此时返回值是id
NSString *str = [[Person alloc] init];
// Person并没有length方法, 但是id是动态类型, 所以编译时不会报错,说明:新版本Xcode编译也会有警告了,警告信息和返回值类型为instancetype的一致
NSLog(@"length = %i", str.length);
// init此时返回值是instancetype
// 由于instancetype它会进行类型检查, 所以会报警告
NSString *str = [[Person alloc] init];
NSLog(@"length = %i", str.length);
instancetype *p = [[person alloc] init];
// 错误写法instancetype只能作为返回值

 根据官方文档案例:

@interface MyObject : NSObject
+ (instancetype)factoryMethodA;
+ (id)factoryMethodB;
@end
 
@implementation MyObject
+ (instancetype)factoryMethodA { return [[[self class] alloc] init]; }
+ (id)factoryMethodB { return [[[self class] alloc] init]; }
@end
 
void doSomething() {
    NSUInteger x, y;
 
    x = [[MyObject factoryMethodA] count]; // Return type of +factoryMethodA is taken to be "MyObject *"
    y = [[MyObject factoryMethodB] count]; // Return type of +factoryMethodB is "id"
}

Because of the instancetype return type of +factoryMethodA, the type of that message expression is MyObject *. Since MyObject doesn’t have a -count method, the compiler gives a warning about the x line:

main.m: ’MyObject’ may not respond to ‘count’
原文地址:https://www.cnblogs.com/xufengyuan/p/6575926.html