
由于init方法,会把对象的属性设置为默认值,基本数据类型赋值为0,C指针数据类型赋值为NULL,OC指针数据类型赋值为nil。
有么有什么办法,能让init方法按照我们自定义的属性,为属性赋值?
答案是,有的,只需要重写init方法。
在.m文件中重写,因为init方法是父类的,所以在@implementation中重写。
@implementation
}
@end
重写init方法的规范:
1)必须要先调用父类的init方法。
[super init];
2)然后,将方法的返回值,赋值给self
self = [super init];
3)调用init方法,初始化对象的时候,是有可能会失败的。如果初始化失败,返回的就是nil,如果返回的不是nil,说明什么,是不初始化成功?
4)判断父类是否初始化成功,即判断self的值是否为nil,如果不为nil,说明初始化成功。
if ( self != nil )
{
self.name = @“jack”;
}
5)如果初始化成功,就初始化当前对象的属性。
6)最后,返回self,返回当前这个对象,把这个已经初始化了的对象,返回给调用者。
1)因为父类的init方法里面,它可能做了一些初始化父类属性的事儿。所以呢,你如果要初始化整个对象的话,你是不也应该把父类的属性给初始化一下啊?
例如:isa指针,是不是指向这个类啊,那这个指针,是在哪儿赋的值,答案是,在NSObject的init方法里面赋的值。如果你不调父类的init方法的话,isa指针有可能就不会指向这个类了
父类的init方法,会初始化父类的属性,所以,必须要保证当前对象中的父类属性,也同时被初始化。
1)[super init]; init方法返回的是什么,是不是初始化成功的那个对象啊,把那个对象赋给self,就是当前那个对象。
2)因为,调用父类的init方法,会返回初始化成功的那个对象
实际上,返回的就是当前对象,但是,我们要判断是否初始化成功,所以必须要赋值一下
3)判断语句,也可以这么写:
self = [ super init];
//0代表假,非0代表真
if ( self )
{
self.name = @“jack”;
}
还可以怎么写?还可以直接就这么写:
if ( self = [ super init ] )
{
self.name = @“jack”;
}
把这个方法的返回值,赋值给self,再判断self的真假。这里不应该写两个等号,只应该写一个等号。
举例,int num = 10;
if ( num = num - 10 )
{
NSLog(@“哈哈哈。。。”);
}
这句话什么意思,是把表达式的结果赋值给num,再判断num的真假。如果是两个等号呢,是判断左右两边的值,是否相等
2)无论如何,记住重写init方法的规范。
- (instancetype)init
{
if(self = [super init])
{
初始化当前类的属性的代码;
}
return self
}
3)这时候,我们再去创建Person对象,
Person对象的name属性还是nil吗,不是了,是@“jack”,为什么,因为init方法被重写了吧。
例如:
Person *p1 = [ Person new];
NSLog(@“p1.name = %@”,p1.name);
new方法的内部调用了init,而init被我们这个子类重写了吧,实际上最后调用的是谁的,是不调用的是子类的啊,在子类里面它给p1对象的name赋了1个jack。
1)如果你希望创建出来的对象的属性的默认值不是nil NULL 0 而是我们指定的值,那么这个时候,我们就可以重写init方法,在init方法里面,为我们对象的属性赋默认值。
2)再比如,有一个Student类,它有一个dog属性,可以在init方法里,创建一个Dog对象,把它赋值给Student对象的dog属性。如下所示:
Student.h:
#import
#import “Dog.h”
@interface Student : NSObject
@property Dog *dog;
@end
Student.m:
#import “Student.h”
@implementation Student
Dog.h:
#import
@interface Dog : NSObject
@property NSString *name;
@property int age;
Dog.m:
#import “Dog.h”
@implementation Dog
main.m:
#import
#import “Dog.h”
#import “Student.h”
int main(int argc, const char * argv[])
{
Student *s1 = [Student new];
[s1.dog shout];
return 0;
}
1)自定义构造方法的规范:
a 自定义构造方法的返回值,必须是instancetype
b 自定义构造方法的名称,必须以initWith开头
c 方法的实现,和init方法一样
d 必须先在.h文件里声明initWith方法
例如:- (instancetype)initWithName:(NSString *)name andAge:(int)age;
这就是,自定义的构造方法,写在Dog.h里:
@interface Dog : NSObject
@property NSString *name;
@property int age;
- (instancetype)initWithName:(NSString *)name andAge:(int)age;
@end
@implementation Dog
- (instancetype)initWithName:(NSString *)name andAge:(int)age
{
if(self = [super init])
{
self.name = name;
self.age = age;
}
return self;
}
2)怎么用,自定义的构造方法?
在main.m中:
#import
#import “Dog.h”
int main()
{
//Dog *d1 = 这时候,就不能在[Dog new];了,因为new方法内部调用的是init方法,现在我们需要调用initWithName: andAge:方法,这时候怎么办呐,就必须先alloc,再调用initWithName: andAge:方法;
Dog * d1 = [ [ Dog alloc] initWithName:@“小黄” andAge:2];
这句话,先用[Dog alloc]创建一个对象,在用自定义构造方法,为这个对象的属性初始化。
3)例如,有一个Person类:
#import
@interface Person : NSObject
@property NSString *name;
@property int age;
@property float weight,height;
@implementation Person