OC关键字@property、@synthesize和id类型、构造方法、分类categary、类的本质、description方法、SEL消息机制

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------


一、关键字@property、@synthesize和id类型

1、使用关键字@property自动生成某个成员变量的set和get方法的声明,例:
@property int age;//-(void)setAge:(int)age;-(int)age;
如果类型一样还可以
@property int height,age;
2、使用关键字@synthesize自动生成_age成员变量的set和get方法的实现,例:
@synthesize age=_age;
如果类型一样还可以
@synthesize height=_height,age=_age;
3、在Xcode4.4以上的版本中@property int age;做了三件事
 1>.生成age的set方法和get方法的声明
 2>.生成了一个以下划线开头的成员变量_age(@protected)
 3>.生成了set方法和get方法的实现
从上可以看出@property独揽了@synthesize的功能
4、注意:@synthesize age=_age;会访问_age这个成员变量,如果不存在,就会自动生成@private类型的_age成员变量
@synthesize age;会访问age成员变量,如果不存在,就会自动生成@private类型的age成员变量
5、使用@property和@synthesize,如果已经生成set方法或者get方法,只要两者缺一,就会自动补齐另一方法的生成或者实现
6、id类型
id是万能指针,能操纵任何OC对象,内部已经包含*,使用时不需要再带*,id==NSObject *//id p = [Person new];

二、构造方法
1、基本概念
用来初始化对象的方法,是对象方法。以-开头
Person *p=[Person new];//完整创建一个可用对象,分配内存空间 +alloc ,初始化-init。Person *p=[[Person alloc] init];
2、重写-init方法

-(id)init{
self=[super init];//调用父类init方法,初始化父类中的一些成员变量和其他属性
if(self!=nil){//初始化成功
_age=10;
}
return self;//返回一个已经初始化完毕的对象
}
//一定要合并成这样的
-(id)init{格式是固定的
if(self=[super init]){//初始化成功
_age=10;只有这儿可以自己改动
}
return self;//返回一个已经初始化完毕的对象
}
3、如果调用父类里面的成员变量属性则可以这样写
-(id)init{//格式是固定的
if(self=[super init]){//初始化成功
_age=10;//只有这儿可以自己改动
self.name = name;//调用父类里面的成员变量
self.no = no;
}
return self;//返回一个已经初始化完毕的对象
}
4、重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
5、重写构造方法步骤:
 1>.线调用父类的构造方法([super init])
 2>.在进行子类内部成员变量的初始化
6、方法的执行过程如图


7、自定义构造方法
 1>.规范:一定是对象方法,以-开头,返回值一般是id类型,方法名一般以initWith开头
 2>.声明
-(id)initWithName:(NSString *)name;
 3>.实现

-(id)initWithName:(NSString *)name{
if(self=[super init]){
_name = name;
}
return self;
}
 4>.调用Person *p=[[Person alloc]  initWithName:@Rose];
8、如果调用父类的成员变量,开发中常这样写,父类的东西在父类里初始化,我的东西在我的里面初始化
-(id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no{
if(self=[super init initWithAge:age andno:no]){//age和no是父类的东西
_name = name;
}
return self;
}
9、调用Person *p=[[Person alloc] initWithName:@Rose andAge:29 andNo:8];
三、分类categary
1、分类:不修改原来类的内容的基础上,给某一个类扩充一些方法
2、格式
@interface 类名(分类名称)
@end
@implementation 类名(分类名称)
@end
3、步骤
 1>.新建categary
categary+分类名称
categary on+类名
 2>.作用:可以把一个类的某类功能分类到一起,分模块命名
 3>.注意:1.分类只能增加方法,不能增加成员变量,但是可以访问成员变量
         2.分类可以重新实现原来类中的方法,但是会覆盖原来的方法,会导致原来的方法无法再使用
         3.方法调用优先级:分类(多个分类的情况下最后参与编译的分类优先)->原来类->父类
command+F快速查找
command+/快速注释
4、给NSString增加类方法
 1>.给NSString(系统自带)增加一个类方法,计算某个字符串在阿拉伯数字的个数
 2>.给NSString增加一个对象方法,计算当前字符串中阿拉伯数字的个数

#import <Foudation/Foudation.h>//NSString+Number.h
@interface NSString (Number)
+(int)numberCountOfString:(NSString *)str;
-(int)numberCount;
@end

#import "NSString+Number.h"//NSString+Number.m
@interface NSString(Number)
+(int)numberCountOfString:(NSString *)str{//类方法
int count = 0;
for(int i = 0;i<str.length;i++){
unichar c = [str characterAtIndex:(NSUImteger)];
if(c>='0'&&c<='9'){
count++;
}
}
return count;
}
-(int)numberCount{//对象方法
int count = 0;
for(int i = 0;i<self.length;i++){
unichar c = [self characterAtIndex:i)];
if(c>='0'&&c<='9'){
count++;
}
}
return count;
}
@end

#import <Foudation/Foudation.h>
#import "NSString+Number.h"
int main(){
int count = [NSString numberCountOfString:@"d87fd8s"];//调用类方法
NSLog(@"%d",count);
int count = [@"d87fd8s",numberCount];//调用对象方法
NSLog(@"%d",count);
return 0;
}
四、类的本质
1、类本身也是一个对象,是Class类型的对象,简称类对象
Class类型定义:
typedef struct objc class *Class
#import <Foudation/Foudation.h>
@interface Person:NSObject
@property int age;
@end

@implementation
@end

#import <Foudation/Foudation.h>
#import "Person.h"
int main(){
Person *p = [[Person alloc] init];//利用Person这个类创建了Person类型的对象
//获取类对象Person的两种方式
Class c=[p class];//第一种
Class c=[Person class];//第二种
return 0;
}
2、类的加载和初始化
 1>.先加载父类再加载子类
 2>.当程序启动的时候,就会加载一次项目中的所有类(包括分类)。类加载的时候就会调用+load方法
+(void)load{
NSLog(@"类被加载的时候调用");
}
 3>.当第一次使用这个类的时候就会调用一次+initialize方法(优先调用分类的+initialize方法),是类的初始化
优先级:先初始化父类在初始化子类,先调用父类+initialize方法,在调用子类的+initialize的方法
+(void)initialize{
NSLog(@"类第一次被调用的时候调用一次本方法");
}
 4>.作用:可以监听类什么时候被调用
五、description方法(NSObject自带的方法)
1、NSLog工作机制
 1>.会调用对象的-description方法
 2>.拿到-description方法的返回值(NSString *)显示到屏幕上
 3>.-description的方法默认返回的是“类名+内存地址”
 4>.如果想要使NSLog输出时,输出的不是“类名+内存地址”,就需要重写-description方法,例
-(NSString *)description{
return [NSString stringWithFormat:@"age=%d,name=%@",_age,_name];
}
调用时
Person *p = [[Person alloc] init];//p为Person对象
NSLog(@"%@",p);//这时输出的就是类的属性
2、+description方法
Class c=[Person class];
NSLog(@"%@",c);
 1>.决定了类对象的输出结果
 2>.默认情况下调用类对象+description方法
3、NSLog输出机制
Person *p = [[Person alloc] init];
NSLog(@"%@",@p);  取出指针变量自己的地址
NSLog(@"%p",p);  指针里面存储对象的地址
NSLog(@"%@",p);  类名+对象地址
NSLog(@"%d",_LINE_); 输出当前行号
NSLog(@"%s",_FILE_); 输出源文件名称
NSLog(@"%s",_func_); 输出函数名
注意:NSLog输出C语言字符串时,不能有中文
六、SEL(消息机制)
1、每个方法在内存中都有一个SEL数据给他对应
2、Person *p = [[Person alloc] init];
[p test];//调用test,为Person对象方法
 1>.把test包装成SEL类型的数据
 2>.根据SEL数据找到对应方法的方法
 3>.根据方法地址调用对应方法
[p performSelector:@selector(test)];//第二种调用test对象的方法
 4>.有时候方法里面需要传递参数
[p performSelector:@selector(test:) withObject:参数];//别忘记(test:)里面加冒号
5、SEL类型的定义
typedef struct objc_selector*SEL;
6、SEL对象的创建
SEL s = @selector(test:);
7、方法名是字符串时,把字符串转成SEL类型数据
NSString *name = @"test2";
SEL s2 = NSSelectorFromString(name);//
[p performSelector:s2];
8、把SEL类型数据转换成字符串
NSString *str = NSStringFromSelector(_cmd);//_cmd代表当前方法
9、SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址,找到辅助的地址就可以调用方法



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值