黑马程序员--OC自学笔记---05点语法、@property、@synthesize、动态类型、id类型、响应方法、构造方法

来源:互联网 发布:天天pk10计划软件 编辑:程序博客网 时间:2024/05/01 20:57

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


 

1.   点语法介绍和使用

1)        点语法是xcode的特性,当我们使用的时候,xcode会自动帮我们做一些替换操作。

2)        当类中设置了set和get方法后,在需要调用set和get方法的时候,可以使用 对象名.属性名  的方式来代替使用set和get方法,但是不能认为是直接获取属性值,而是xcode会把点语法替换成对应的set或get方法。

3)        以person类为例说明点语法:↓↓↓

#import<Foundation/Foundation.h>@interfacePerson : NSObject{    int _age;}-(void)setAge:(int)age;-(int)age;@end#import"Person.h"@implementationPerson-(void)setAge:(int)age{    _age = age;}-(int)age{    return _age;}@end#import<Foundation/Foundation.h>#import"Person.h"int main(intargc, const char * argv[]) {    @autoreleasepool {               Person *p = [Person new];        //[p setAge:15];        p.age = 15; //这里的点语法使用,掉用的是set方法,编译器会把这句话替换为上面的set方法的调用。       // NSLog(@"age = %d",[p age]);        NSLog(@"age = %d",p.age);//这里的点语法,调用的是get方法,会自动的被替换为get方法的调用形式,和上面的输出语句是等同的。    }    return 0;}

4)        一般情况下,点语法出现在等号左侧为set方法,在等号右侧为get方法。

5)        self使用点语法容易错的用法:

①  在set方法中使用点语法,误认为self和java中的this用法相同,这里的self.age其实是再次调用set方法(这里是-(void)setAge:(int)age)本身,所以会造成死循环

-(void)setAge:(int)age{            self.age = age;}

②  在get方法中,同样把self当做this一样来使用,实际上self.age是调用get方法(这里是-(int)age)本身,也会造成死循环

-(int)age{    return self.age;} 

6)        点语法使用注意:点语法的本质是方法的调用,而不是访问成员变量,当使用点语法时,编译器会自动展开成相应的方法。切记点语法的本质是转换成相应的setget方法,如果没有setget方法,则不能使用点语法。

 

2.   @property关键字

1)        概念:@property是编译器的指令,就是用来告诉编译器要做什么,@property告诉编译器声明属性的访问器(setter/getter)方法,这样可以免去我们手工去声明set和get方法

2)        使用格式:@property  数据类型  方法名(去掉set)

3)        作用:

①  在xcode 4.4之前,用于帮我们实现set/get方法的声明(没有实现)。

②  在xcode 4.4之后,有增强功能

4)        @property只能写在@interface和@end之间

5)        告诉property要生成的get/set方法声明的成员变量的类型是什么

6)        告诉property要生成的get/set方法是哪个属性的,属性名称去掉下划线

7)        注意:用@property声明的方法名如果改变,则对应的实现方法的名称也必须改变,否则会出错。

3.   @synthesize关键字

1)        是在.m文件中实现set和get方法

2)        格式为@synthesize  方法名

@synthesize  name

等同于:-(void)setName:(NSString *)name{_name = name;}

        -(NSString*)getName{return _name;}

3)        关于这个方法名的方法在.h文件中要先用@property声明

4)        如果使用@property和@synthesize的方法名在.h中没有声明,则系统会自动生成一个新的变量

5)        对指定的实例变量赋值:@synthesize  方法名 =  实例变量名

表示对指定的实例变量,实现其set/get方法,方法的名称为指定方法名,不再默认生成新的实例变量

@synthesize age=_age;

等号左侧的名称不管是什么,都是对等号右边的实例变量实现set/get方法。

-(void)setAge:(int)age{       _age = age;}-(int)age{        return _age;}

4.   @property的增强功能

举例说明:@property  int age;

1)        在xcode4.4 以后,可以只使用@property而不使用@synthesize

2)        @property会自动声明和实现_age的get和set方法

3)        操作的是带有下划线的对应实例变量,这里就是_age

4)        如果当前类没有定义带下划线的实例变量,系统会自动帮我们生成(系统自动定义一个int _age;)

5)        系统自动生成的实例变量是私有的,不能被子类继承。

6)        Set和get方法在.m文件中可以自己手动实现,但是get和set方法不能同时手动实现

5.   动态类型和静态类型

多态:允许不同的类定义相同的方法

动态类型:程序直到执行时才能确定所属的类

静态类型:将一个变量定义为特定类的对象时,使用的是静态类型

使用动态类型进行编译时和运行时的检查。

6.   id类型

1)        id是一种通用的对象类型,它可以用来存储属于任何类的对象,也可以理解为万能指针

Animal  *ani =[Animal new];Dog * dog = [Dog new];id = ani;id = dog;

2)        在id的定义中,已经包好了*号,id指针只能指向OS的对象

3)        NSObject和id都可以指向任何对象

4)        NSObject对象会进行编译时检查(需要强制转换类型)

5)        Id不需要强制类型转换,id可以直接使用

6)        编译器看到id以后,认为是动态类型,不再检查类型。

7)        iOS5以后推出了instancetype类型,和id的异同:

①  都可以作为方法的返回类型

②  Instancetype可以返回和方法所在类相同类型的对象,id只能返回未知类型的对象

③  Instancetype只能作为返回值,不能像id那样作为参数

7.   动态类型检测

对象在运行时获取其类型的能力称为内省。内省可以有多种方法实现。

1)        判断类型-(BOOL)isKindOfClass:classObj 判断实例对象是否是这个类或者这个类的子类的实例

使用格式:

[对象  isKindOfClass:类对象]

BOOL  b = [dogisKindOfClass:[Animal class]]; //b=1;

2)        -(BOOL)isMemberOfClass:classObj  判断实例对象是否是当前类的实例

格式为 [对象 isMembeOfClass: 类对象]

BOOL b = [dog  isMemberOfClass:[Animalclass]];//b=0;

 

3)        -(BOOL)isSubclassOfClass:classObj判断某个类是否是指定类的子类

格式为:[类名/类对象  isSubclassOfClass:类对象]

 BOOL  b =[Dog isSubclassOfClass:[Animal class]];  //b=1        

8.   方法响应(调用)的检测

1)        判断实例对象能否响应(调用)制定的方法

-(BOOL)reapondsToSelector:(SEL)selector

格式:对象  respondsToSelector:方法的sel类型

举例:SEL  s = @selector(run):

BOOL  b = [ani  rspondsToSelector:s];

判断ani能否调用run方法

2)        判断类能否响应指定的方法(即判断类是否有指定方法)

+(BOOL)instanceRespondToSelector:

BOOL  b = [Dog  instanceRespondToSelector:@selector(run)];

判断Dog类中是否有run方法。

9.   响应方法

1)        -(id)performSelector:selector(应用selector指定的方法)

2)        通过performSelector调用无参方法

SEL  s1 =@selector(eat);

Dog  *dog = [Dog  new];

[Dog  performSelector:s1];

3)        通过performSelector调用一个参数的方法

SEL  s2 =@selector(eat:);

[dog performSelector:s2  withObject:@”狗粮”];

4)        通过performSelector调用两个参数的方法

SEL  s3 =@selector(eat: andFoodName);

[Dog performSelector:s3  withObject:@”大黄狗” withObject:@”狗粮”];

5)        performSelector最多只能调用两个参数的方法。

10. 构造方法

1)        给对象进行初始化的方法为构造方法

2)        OC中给对象进行初始化的方法是   init方法,init方法是一个对象方法,该方法返回的是一个对象(调用init方法的对象)

3)        关于alloc

①  想某个类发送alloc消息的结果

②  为该类分配内存,以存放该类的全部实例变量

③  还将这块内存区域全部初始化为0

4)        注意:

①          个刚刚分配的对象并不能立即使用

②          需要县初始化该对象,然后才能使用它

③          但由于未进行初始化,随后可能出现一些不可预测的行为

5)        重写构造方法init

-(instancetype)init{    //先调用父类的初始化方法,完成默认的初始化操作    self = [super init];    //判断父类是否初始化成功    if (self) {        //子类初始化的代码        _age = 10;    }    //self指代的是方法的调用者    return self;}

      初始化理论分析:

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

②  self为什么要赋值为[super init]?

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

③  super作为消息接收者的实质:

super并不是真正的指针,[super message]的实质是由self来接收父类的message。需要注意的是,[super message]中,message方法出现的self为[super message]语境中的self,即子类实例。

6)        自定义构造方法

①  一定是对象方法,以减号开头

②  返回值一般是id类型

③  方法名一般以initWith开头

注意:

①  自己做自己的事情

②  父类的方法交给父类的方法来处理,子类的方法处理子类自己独有的属性

自定义构造方法应用:

//父类Person类#import<Foundation/Foundation.h>@interfacePerson : NSObject@property intage;@propertyNSString *name;-(instancetype)initWithName:(NSString*)name andAge:(int)age;@end#import"Person.h"@implementationPerson-(instancetype)initWithName:(NSString*)name andAge:(int)age{    if(self = [super init]){        _name = name;        _age = age;    }    return self;}@end //子类Student类#import"Person.h"@interfaceStudent : Person@property intsno;-(instancetype)initWithName:(NSString*)name andAge:(int)age andSno:(int)sno;@end#import"Student.h"@implementationStudent-(instancetype)initWithName:(NSString*)name andAge:(int)age andSno:(int)sno{    if (self = [super initWith:nameandAge:age]) {        _sno = sno;    }    return self;}@end //主函数#import<Foundation/Foundation.h>#import"Student.h"int main(intargc, const char * argv[]) {    @autoreleasepool {               Student *stu = [[Studentalloc]initWithName:@"cjk" andAge:38 andSno:438];        NSLog(@"name = %@,age = %d,sno =%d",stu.name,stu.age,stu.sno);    }    return 0;}



0 0
原创粉丝点击