1.new方法实现原理 完整的创建一个可用的对象:Person *p=[Person new]; new方法的内部会分别调用两个方法来完成3件事情: (1)使用alloc方法来分配存储空间(返回分配的对象); (2)使用init方法来对对象进行初始化。 (3)返回对象的首地址 可以把new方法拆开如下: (1)调用类方法+alloc分配存储空间,返回未经初始化的对象```Person *p1=[person alloc]; (2)调用对象方法-init进行初始化,返回对象本身 Person *p2=[p1 init]; (3)以上两个过程整合为一句:```Person *p=[[Person alloc] init]; init方法是初始化方法(构造方法),用来对象成员变量进行初始化,默认实现是一个空方法。 所以下面两句的作用是等价的 Person *p1 = [Person new]; Person *p = [[Person alloc] init]; 2.重写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中的语句。 实现通过Person类创建出来的人初始化值都是10岁。 @implementation Person - (instancetype)init { if (self = [super init]) { _age = 10; } return self; } @end 3.构造方法使用注意 子类拥有的成员变量包括自己的成员变量以及从父类继承而来的成员变量,在重写构造方法的时候应该首先对从父类继承而来的成员变量先进行初始化。 原则:先初始化父类的,再初始化子类的。 先调用父类的构造方法[super init]; 再进行子类内部成员变量的初始化。 注意千万不要把`self = [super init]`写成self `==` [super init] 重写构造方法的目的:为了让对象方法一创建出来,成员变量就会有一些固定的值。 4.自定义构造方法的出现 有时候仅仅靠重写构造方法(初始化方法),不能满足需求。比如一个班级中不可能所有学生的年龄都一样,这时候我们需要在创建某个学生的时候能够传入这个学生的年龄。这时候就需要来自定义构造函数(初始化函数) 自定义构造方法的规范 (1)一定是对象方法,以减号开头 (2)返回值一般是instancetype类型 (3)方法名必须以initWith开头 - 示例 @interface Person : NSObject @propertyint age; @propertyNSString *name; // 当想让对象一创建就拥有一些指定的值,就可以使用自定义构造方法 - (id)initWithAge:(int)age; - (id)initWithName:(NSString *)name; - (id)initWithAge:(int)age andName:(NSString *)name; @end ``` 自定义构造方法的使用注意 (1)自己做自己的事情 (2)父类的属性交给父类的方法来处理,子类的方法处理子类自己独有的属性 自定义构造方法必须以intiWith开头,并且’W’必须大写 5.子父类中的类工厂方法 由于之类默认会继承父类所有的方法和属性, 所以类工厂方法也会被继承 由于父类的类工厂方法创建实例对象时是使用父类的类创建的, 所以如果子类调用父类的类工厂方法创建实例对象,创建出来的还是父类的实例对象 为了解决这个问题, 以后在自定义类工厂时候不要利用父类创建实例对象, 改为使用self创建, 因为self谁调用当前方法self就是谁 示例 @interface Person : NSObject (id)person; @end @implementation Person (id)person { return [[Person alloc]init]; } @end @interface Student : Person @propertyNSString *name; @end @implementation Student @end int main(intargc, const char * argv[]) { Student *stu = [Student person];// [[Person alloc] init] [stusetName:@"lnj"]; // 报错, 因为Person中没有setName } - 正确写法 @interface Person : NSObject + (id)person; @end @implementation Person + (id)person { // return [[Person alloc]init]; // 谁调用这个方法,self就代表谁 // 注意:以后写类方法创建初始化对象,写self不要直接写类名 return [[self alloc]init]; } @end @interface Student : Person @propertyNSString *name; @end @implementation Student @end int main(intargc, const char * argv[]) { Student *stu = [Student person];// [[Student alloc] init] [stusetName:@"lnj"]; } |