目录:
1.OC中的方法
2.设置器 与 访问器
3.便利初始化函数 与 便利构造器
-OC中的方法
定义:类的功能代码,在(.h)文件名中声明,在(.m)文件中实现。
语法: -|+ (返回类型)方法名:参数列表
{ 方法体 }
其中减号 (-) 表示实例方法,加号 (+) 表示类方法
实例方法例子:
- (void)sayHello;
- (void)sayHelloName:(NSString *)name
Age:(NSInteger)age;
类方法例子:
+ (void)sayHi;
+ (void)hiGuys;
使用类方法时,要注意以下四点:
1)类方法可以调用类方法
2)类方法不可以调用实例方法,但是类方法可以通过创建对象来访问实例方法
3)类方法不可以使用实例变量,类方法可以使用self,因为self不是实例变量
4)类方法作为消息,可以被发送到类里面去,不能发送到对象里面去
例如:
1)类方法可以调用类方法
+ (void)hiGuys{
//self 代表当前对象的指针
[self sayHi];
}
2)类方法不可以调用实例方法,但是类方法可以通过创建对象来访问实例方法
Person *person1 = [Person new];
[person1 sayHello ];
3)类方法不可以使用实例变量,类方法可以使用self,因为self不是实例变量
NSLog(@" name : %@ , age : %ld, hobby : %@",_name, _age, _hobby);
以上代码不能运行
4)类方法作为消息,可以被发送到类里面去,不能发送到对象里面去
[person sayHi];
以上代码不能运行
设置器(setter) 与 访问器(getter)
作用:1)隐藏了实例变量
2)控制了实例变量的读写
3)做正确性的校验
设置器 和 访问器 的命名规则
1)设置器: - (返回类型)set首字母大写的实例变量:(实例变量的返回值类型)去掉下划线的实例变量名
2)访问器: - (实例变量返回值类型)去掉下划线的实例变量名
例如:
- (void)setName:(NSString *)name;
- (NSString *)name;
使用 setter 和 getter 的好处:
1)在 setter 中可以加入合法性检查,比如设置颜色的函数中,对于RGB颜色要判断其值在 0-255 之间
2)更新与被设置变量相关的其他变量的值,比如在一个潜水艇模拟系统中,改变了其水下深度时,要响应的更新所受压强。
3)在 debug 时,可以在其中,尤其是在 setter 中加入追踪 log。
4)在多线程环境中,如果要保护对象的并发访问,则必须在 getter/setter 中加入同步锁
-我们可以对 age 属性进行正确性校验
创建一个Student类,在接口文件中定义成员变量age,并写好设置器与访问器
{
NSString *_age;
}
- (void)setAge:(NSInteger)age;
- (NSString)age;
在实现文件中写入
- (void)setAge:(NSInteger)age{
_age = age;
if (age < 18) {
_age = 18;
}
else{
_age = age;
}
}
- (NSInteger)age{
return _age;
}
在main.m文件里进行校验
Student *student1 = [[Student alloc] init];
[student1 setAge:10];
NSLog(@"age = %ld",name);
运行结果为 age = 18
Student *student1 = [[Student alloc] init];
[student1 setAge:25];
NSLog(@"age = %ld",name);
运行结果为 age = 25
便利初始化函数
通过上面代码我们可以对对象进行赋值,但实际使用时,对象和对象的实际变量的值往往是不同的,所以我们需要在init方法调用时传入个性化数据。这时候就需要用到便利初始化函数。
例如
在接口文件中写入
{
NSString *_name;
NSInteger _age;
}
- (void)sayWord{
- (id)initWithName:(NSString *)name
Age:(NSInteger)age;
在实现文件中写入
- (void)sayWord{
NSLog(@"Hello , my name is %@ , I am %ld years old", _name, _age);
}
- (id)initWithName:(NSString *)name
Age:(NSInteger)age{
if (self = [super init]) {
_name = name;
_age = age;
}
return self;
}
在main.h中写入
Teacher *teach1 = [[Teacher alloc] initWithName:@"Jack" Age:25];
[teach1 sayWord];
运行结果为:Hello , my name is Jack , I am 25 years old
便利构造器
便利构造器,只不过是把 对象分配内存 和 调用便利初始化函数初始化对象 的代码封装起来,让用户使用更加方便
在接口文件中写入
{
NSString *_name;
NSInteger _age;
}
- (void)sayWord;
+ (id)teacherWithName:(NSString *)name
Age:(NSInteger)age;
在实现文件中写入
- (void)sayWord{
NSLog(@"Hello , my name is %@ , I am %ld years old", _name, _age);
}
+ (id)teacherWithName:(NSString *)name Age:(NSInteger)age{
Teacher *teacher = [[Teacher alloc] initWithName:name Age:age];
return teacher;
}
在main.h中写入
Teacher *teach2 = [[Teacher alloc] initWithName:@"Jack" Age:25];
[teach2 sayWord];
运行结果为:Hello , my name is Jack , I am 25 years old
使用时注意的一些概念:
id:返回的类型是 id 数据类型,它是动态数据类型,可以指向任何类的对象,而不关心其具体类型
在运行时检查其具体类型,可以对其发送任何(存在的)消息
self:值当前对象的指针
super:指向父类对象的指针,子类使用 super 发送消息的时,实际上就是告诉子类调用父类的方法
如果父类没有定义该方法,则继续在继承链上查找,直到寻找到位置
如果找到 NSobject 的位置还没找到,就会报错