当前位置: 首页 > >

黑马程序员??IOS基础之OC??@property、动态检测与构造方法讲解

发布时间:

??Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ??


第一章@property的讲解

    传统的getter和setter
    在OC中为了保护数据的安全和编程,OC中对实例变量进行初始化和实例变量运用都采用了对象方法对其实现。OC中把这两种方法称作setter和getter,seter方法就是对实例变量进行初始化或者赋值,getter方法就是对实例变量进行访问。有了这两个方法后,OC中的主程序需要对实例变量赋值或者访问时就可以直接调用这个方法。
    setter和getter示例

@interface Person : NSObject
{
int _age;
NSString *_name;
}
//实例变量_age和_name的赋值方法
-(void)setAge:(int)age;
-(void)setName:(NSString *)name;
//实例变量_age和_name的访问方法
-(int)age;
-(NSString *)name;
@end

    点语法的介绍和使用
    OC中对对象方法进行访问时的程序块是相对繁琐的,为了解决这一问题OC中引进了点语法来简化这一步骤。它是xcode的特性。它的代码如下:

#import
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [Person new];
//传统调用调用方法
[p setAge:18];
[p setName:@"张无忌"];
//点语法的方法
p.age = 18;
p.name = @"张三丰";
}
return 0;
}

点语法使用注意
- 格式:对象.属性名
- 点语法是xcode的特性,xcode帮我们做了代码的替换,即p.age并不是直接访问实例变量,而是xcode看到点语法后,如果是设置值会自动帮我们替换成[p setAge:18],如果是取值会自动帮我们替换成[p age]
- p.age到底是替换成get方法还是set方法,一般取决于p.age出现在等号的左侧还是右侧即是设置值还是取值

3. @property介绍
OC意识到当getter方法和setter方法遇到一个类有大量的实例变量时,getter方法和setter方法的 声明和实现将会变的非常繁琐,这时OC就有了@property的产生。即当OC中使用@property时就同时声明了setter和getter方法。这时OC就要解决另外一个问题?方法的实现。所以OC就使用@synthesize来让方法的实现也变的容易。
代码如下


@interface Person : NSObject
{
int _age;
NSString *_name;
}
//@property的格式:@property 类型名 方法名(去掉下划线的实例变量)
@property int age;//相当于-(void)setAge:(int)age;-(int)age;
@property NSString *name;//-(void)setName:(NSString *)name;-(NSString *)name;
@end

@implementation Person
//@synthesize的格式:1.@synthesize 方法名(此时方法名作为我们系统生成的变量名)
//2.@synthesize 方法名 = 实例变量名(给指定的变量赋值)
@synthesize age;
/*
@sythesize相当于给getter和setter方法的实现进行了替代
-(void)steAge:(int)age{
self->age = age;
}
-(int)age{
return age;
}
*/
@synthesize name;
-(void)name:(NSString *)name{
self->name = name;
}
-(NSString *)name{
return name;
}
@end

使用注意:当两个或多个实例变量的类型一致的时候OC中规定可以将多个实例变量的声明和实现写在同一个语句


@interface Person : NSObject
{
int _age;
NSString *_name;
int _height
}
@property int age,height;//_age和_height同类型
@property NSString *name;
@end

@implementation Person
//@synthesize可以将不同类型的写在一起,但是为了书写规范OC中一般不写在一起
@synthesize age,height,name;
@end

@property的增强,在xcode4.4之前必须要写上@synthesize才能实现方法的实现,但是在xcode4.4之后OC中的@property指令就增强了,我们就不需要写@synthesize,@property指令就相当于实现了方法的声明和方法的实现。这对使用者来说是非常方便的,还需注意的一点是当我们需要方法的实现有特殊的功能时,这时就需要对方法的实现进行重写,如果我们用了@property指令的话,那么方法的重写就只能重写getter和setter方法中的一个。因为编译器认为如果你两个都重写了,那还用@property指令就显得重复了。


第二章 动态检测
动态类型的检测主要从以下几个方面:1)判断类型包括,判断某个未知的对象是否为类的实例对象或者子类的实例对象;判断某个未知的对象是否为指定类的实例对象;判断类是否为指定类的子类。2)方法响应的检测包括,某个实例对象是否能响应指定的方法;某个类能否响应指定的方法。3)动态类型检查响应方法,包括无形参,两个形参,多个形参的情况。
1)第一部分判断类型

Animal *a = [Animal new];
Dog *d = [Dog new];
Person *p = [Person new];
//1.判断某个对象是否为类的实例对象或者子类的实例对象
//iskindofclass使用格式:[对象 iskindofclass 类对象];
BOOL isInstance = [a isKindOfClass:[Animal class]];//如果是就是YES即真,不是就是NO即假
//2.判断某个对象是否为指定类的实例对象(不包括子类)
//ismemberofclass使用格式:[对象 ismemberofclass 类对象];
isInstance = [d isMemberOfClass:[Animal class]];//如果是就是YES即真,不是就是NO即假
//3.判断类是否为指定类的子类
//isSubClass格式:[类A isSubclass:类B]
BOOL isSub = [Dog isSubclassOfClass:[Animal class]];//如果是就是YES即真,不是就是NO即假
//通过对象来获取类对象Dog = [d class]
isSub = [[d class] isSubclassOfClass:[Animal class]];//如果是就是YES即真,不是就是NO即假
isSub = [Person isSubclassOfClass:[Animal class]];//如果是就是YES即真,不是就是NO即假

2)方法响应的检测

//1.方法响应的检测
Animal *a = [Animal new];
//判断实例对象能否响应指定的方法
//格式: 对象 respondsToSelector:方法
SEL s1 = @selector(eat);//方法需要包装成SEL
BOOL isRespond = [a respondsToSelector:s1];//如果是就是YES即真,不是就是NO即假
//判断类能否响应指定的方法
//格式:类 instancesRespondToSelectot 方法
isRespond = [Dog instancesRespondToSelector:s1];//如果是就是YES即真,不是就是NO即假
//父类中有此方法
isRespond = [Dog instancesRespondToSelector:@selector(run)];//如果是就是YES即真,不是就是NO即假

3)动态类型检查响应方法,通过performSelecter实现对象和方法之间的响应即取代[对象名 方法名]。

//动态类型检查响应方法
Animal *a = [Dog new];
SEL s1 = @selector(eat);
//通过performSelector响应无参的方法
if ([a respondsToSelector:s1]) {
//[(Dog *)a eat];
[a performSelector:s1];
}else{
NSLog(@"该对象不能调用此方法");
}
//通过performSelector:withObject:响应有参的方法
SEL s2 = @selector(eat:);
[a performSelector:s2 withObject:@"棒棒糖"];
//通过performSelector:withObject:withObject:调用两个参数的方法
[a performSelector:@selector(eat:and:) withObject:@"lala" withObject:@"不知道"];

第三章 构造方法讲解
OC中的构造方法就是给对象初始化的方法,OC中初始化方法采用的是init方法,init是一个对象方法,init方法返回的是一个对象。OC中的构造方法主要学*的是构造方法的重写,让对象创建成功后就有初始的值。
构造方法的重写原理:当子类的init覆盖了父类的,这时候默认执行的是子类的。

@implementation Person
//当子类把父类的init覆盖了,这时候默认的先执行子类的
- (instancetype)init{
//先让父类先把父类的事做完,不然可能父类初始化的值会变成空
self = [super init];//super是调用父类的方法
//判断父类是否初始化完成
if (self) {
//此处写子类初始化类容
_age = 10;
}
return self;//self指代的是方法的调用者
}
@end

自定义构造方法:在程序中我们往往要用指定的值对实例变量进行初始化,创建对象的时候,用我们指定的名字和年龄进行初始化。OC中可以自定义构造方法去完成这一个需求。自定义构造方法是一个对象方法,返回值是id(instancetype)类型,必须以initwith开头。

//自定义构造方法的声明
@interface Person : NSObject
@property NSString* name;
@property int age;
-(instancetype)initWithName:(NSString *)name andAge:(int)age;
@end
//自定义构造方法的实现示例
@implementation Person
-(instancetype)initWithName:(NSString *)name andAge:(int)age{
if (self = [super init]) {
_name = name;
_age = age;
}
return self;
}
@end
//自定义构造方法的调用
Person *p = [Person new];
Person *p1 = [[Person alloc] initWithName:@"xiaoming" andAge:18];



友情链接: