IOS学习---OC基础学习4
2014-10-23 22:46
253 查看
点语法:
Person类中有_age一个成员变量;
设置成员变量_age的值:
Person *p = [Person new]
p.age = 10;[p setAge:10];
获取成员变量的值:
int a = p.age;[p age];
根据有无赋值判断是get方法还是set方法
点语法的本质还是方法调用(可通过在set和get方法中设置验证语句验证)
单步调试在Xcode中底面输出栏上面类似下载的按钮
成员变量作用域:
当类在声明成员变量时加入@public,那么在任何地方都可以直接访问对象的成员变量
当类在声明成员变量时加入@private,那么不允许直接访问类的成员变量只能使用set和get方法(只能在当前类的方法对象方法中直接访问)
当类在声明成员变量时加入@protected,那么只能在当前类和子类的对象方法中直接访问(默认为protected)
类的成员变量 既可以在.h(声明文件)文件中声明 也可以在.m(实现文件)文件中声明。但是在.h文件中声明默认是protected而在.m文件中声明默认是privated类型(也可以通过setter和getter方法访问)(注意:成员变量名不能与声明文件中的成员变量名相同)(原因:其他文件无法import.m文件因此其他文件无法使用该成员变量)
@property int age;相当于生成age的set和get方法;
@synthesize age(方法声明名) = _age(成员变量名):
自动生成@property声明 age的setter和getter方法,并且会访问—_age这个成员变量
也可以同时实现几个方法
@synthesize age=_age,name=_name;
@synthesize age=_age,name=_name;
执行此句时会访问_speed这个成员变量,如果不存在,就会自动生成@private类型的_speed变量
缺点:自动生成的类型为private类型
注意:如果写为:
1、@synthesize age;则会自动生成名字为age(不是_age)的成员变量的set和get方法
2、如果@implementation中已经有了set和get方法 在使用@synthesize时不会自动生成以_下划线开头的成员变量
id类型:
万能指针,能指向\操纵任何OC对象
id d = [Person new];//注意id后面没有*号
相当于
NSObjct *o = [Person new]; // 多态 id = NSObject*
id 相当于可以指向任何一个NSObjct的子类,形成类似多态的形式
构造方法:
Person *p = [Person new];
完整的 创建一个可用对象
1.分配存储空间 +allo
2.初始化 -init
1、调用+alloc分配存储空间
Person *p = [Person alloc];
2、调用-init进行初始化
Person *p2 = [p1 init];
1+2 = Person *p = [Person new];
也可以写为:Person *p3 = [[Person alloc] init];
以后创建新的对象不要在用new了 改为两步走
构造方法:用来初始化的方法,是一个构造方法(-开头)
重写构造方法:
例子:重写init方法
- (id)init
{
//1、一定要调用回super(父类)的init方法:初始化父类//中声明的一些成员变量和其他属性
self = [super init];//当前对象self
if(self !=nil); // nil==0
{
//2初始化成功 才有必要进行接下来的初始化
_age = 10;//初始化
}
//3、返回一个已经初始化完毕的对象
return self;
}
可以简写为
- (id)init
{
//super调用的是直接父类
if(self = [super init]); // nil==0
{
_age = 10;
}
return self;
}
总结:
重写构造方法的目的:
为了让对象创建出来,成员变量就会有一些固定的值
重写构造方法的注意点:
1、先调用父类的构造方法(self = [super init])
2、在进行子类内部成员变量的初始化
自定义构造方法:
1、一定是对象方法,一定以-开头
2、返回值一般为id类型
3、方法名一般以init开头
例子:
- (id)initWithName:(NSString*)name;
- (id)initWithName:(NSString*)name
{
if(self = [super init])
{
_name = name;
//如果遇到某些父类的变量为私有变量
[self setName:name];
[super setName:name];
sefl.name=name;
}
return self;
}
调用:Person *p = [[Person alloc] initWithName:@"rose"];
写程序时:能调用原来的程序就不要重复写原来的代码!
谁声明的变量由谁来进行赋值
父类的属性(成员变量)交给父类来处理,子类方法处理子类自己的属性(成员变量)
分类(Category )(类别、类目):
可以给某个类扩充一些方法(不修改原来的代码)
//声明
@interface 类名[分类名称]
@end
//实现
@implementation 类名[分类名称]
@end;
作用:在不改变原来类内容的基础上 可以为类增加一些方法
使用注意:
1、不能扩充成员变量,只能添加方法
2、新增的分类中可以访问成员变量
3、可以直接使用对象调用分类中的方法 分类-原来的类-父类
4、分类的优先级最高,对象调用方法时优先在分类中查找,因此如果分类中重写类中的某个方法,会覆盖掉原来类中的方法,从而导致原来的方法失效
5、方法调用优先级:分类(最后参与编译的分类优先)->原来类->父类
类的本质”
类也是一个对象 是一个class类型的对象 简称类对象
class 类型的定义
typedef struct objc class *class
class 创建 Person类对象
利用Person类对象 创建Person类型的对象
Person *p1 = [[Person alloc] init];
Person *p2 = [[Person alloc] init];
//获取内存中的类对象
class c = [p class];
class c2 = [p2 class];
c 与 c2是相同的
因为p1,p2都是Person类的对象所以内存中的对象类相同
(类对象是否相同可根据对象中的isa的指向进行判断)
另一种获取内存中类对象的方法
class c3 = [Person class];
最终搞得输出结果 c =c2 = c3;
一个类在内存中只有一个存储空间 我们称其为类对象
类的加载顺序:先加载父类 在加载子类
load方法:在类被加载的时候调用 只会被加载一次
initialize方法:当程序启动的时候,会加载一次项目中所有的类,类加载完毕后就会调用load方法
(面试内容)
load方法:程序一启动,加载类的时候被调用,每个类调用一次
initialize方法:第一次用到这个类的时候被调用,总是先调用父类
总结:
1、当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法,只会调用一次、
2、当第一次使用某一个类时,就会调用当前类的+initialize方法
3、先加载父类,在加载子类(先调用父类的+load方法,在调用子类的+load方法)
先初始化父类,在初始化子类(先调用父类的+initialize方法,在调用子类的+initialize方法)
Description:
-description
默认情况下利用NSLog和@输出对象时,结果是<类名:内存地址>
Person *p = [[Person alloc] init];
NSLog(@"%@",p);
执行上述第二句时:
1、会调用对象P的-description方法
2、拿到-description方法的返回值(NSString*)显示到屏幕上
3、-description方法默认返回值是 “类名+内存地址”
因此,要想通过NSLog(@"%@",p)输出p的相关信息就要重写
-description方法
+description:
Class c = [Person class];
NSLog(@"%@",c);
执行上述第二条语句时
1、会调用类的+description方法
2、拿到+description方法的返回值(NSString*)显示到屏幕上
3、+description方法的默认返回值为“类名”
NSLog的扩展输出:
1、NSLog(@"%d",__LINE__);输出当前的行号
//NSLog输出C语言字符串时 不能有中文
2、NSLog(@"%s",__FILE__);输出文件路径(文件路径中不能有中文)
3、NSLog(@"%d",__LINE__);输出当前函数或者方法名
self基本使用:
多种方法调用类中的方法
Person *p = [[Person alloc] init];
[p test2];
执行步骤:
基础:
先利用对象P中的isa指针 到Person类中去寻找 test2方法
而 在Person类中每一个 方法都对应这一个self类的数据(方法的地址)改地址存放于isa指针当中
具体步骤:
1、把test2包装成SEL类型数据
2、去isa中的SEL地址 到Person类中查找对应的方法
3、根据方法地址调用相应的方法
调用方法的两种方法:
1、直接调用
[p test];
第二种 利用SEL=方法名地址
[p performSelector:@selector(test2)];
第三种
每个方法内部都会隐藏一个_cmd 代表当前方法
总结:
SEL其实是对方法的一种包装,将方法包装秤一个SEL类型的数据,去找到相应的方法地址,找到方法地址就可以调用方法
Person类中有_age一个成员变量;
设置成员变量_age的值:
Person *p = [Person new]
p.age = 10;[p setAge:10];
获取成员变量的值:
int a = p.age;[p age];
根据有无赋值判断是get方法还是set方法
点语法的本质还是方法调用(可通过在set和get方法中设置验证语句验证)
单步调试在Xcode中底面输出栏上面类似下载的按钮
成员变量作用域:
当类在声明成员变量时加入@public,那么在任何地方都可以直接访问对象的成员变量
当类在声明成员变量时加入@private,那么不允许直接访问类的成员变量只能使用set和get方法(只能在当前类的方法对象方法中直接访问)
当类在声明成员变量时加入@protected,那么只能在当前类和子类的对象方法中直接访问(默认为protected)
类的成员变量 既可以在.h(声明文件)文件中声明 也可以在.m(实现文件)文件中声明。但是在.h文件中声明默认是protected而在.m文件中声明默认是privated类型(也可以通过setter和getter方法访问)(注意:成员变量名不能与声明文件中的成员变量名相同)(原因:其他文件无法import.m文件因此其他文件无法使用该成员变量)
@property int age;相当于生成age的set和get方法;
@synthesize age(方法声明名) = _age(成员变量名):
自动生成@property声明 age的setter和getter方法,并且会访问—_age这个成员变量
也可以同时实现几个方法
@synthesize age=_age,name=_name;
@synthesize age=_age,name=_name;
执行此句时会访问_speed这个成员变量,如果不存在,就会自动生成@private类型的_speed变量
缺点:自动生成的类型为private类型
注意:如果写为:
1、@synthesize age;则会自动生成名字为age(不是_age)的成员变量的set和get方法
2、如果@implementation中已经有了set和get方法 在使用@synthesize时不会自动生成以_下划线开头的成员变量
id类型:
万能指针,能指向\操纵任何OC对象
id d = [Person new];//注意id后面没有*号
相当于
NSObjct *o = [Person new]; // 多态 id = NSObject*
id 相当于可以指向任何一个NSObjct的子类,形成类似多态的形式
构造方法:
Person *p = [Person new];
完整的 创建一个可用对象
1.分配存储空间 +allo
2.初始化 -init
1、调用+alloc分配存储空间
Person *p = [Person alloc];
2、调用-init进行初始化
Person *p2 = [p1 init];
1+2 = Person *p = [Person new];
也可以写为:Person *p3 = [[Person alloc] init];
以后创建新的对象不要在用new了 改为两步走
构造方法:用来初始化的方法,是一个构造方法(-开头)
重写构造方法:
例子:重写init方法
- (id)init
{
//1、一定要调用回super(父类)的init方法:初始化父类//中声明的一些成员变量和其他属性
self = [super init];//当前对象self
if(self !=nil); // nil==0
{
//2初始化成功 才有必要进行接下来的初始化
_age = 10;//初始化
}
//3、返回一个已经初始化完毕的对象
return self;
}
可以简写为
- (id)init
{
//super调用的是直接父类
if(self = [super init]); // nil==0
{
_age = 10;
}
return self;
}
总结:
重写构造方法的目的:
为了让对象创建出来,成员变量就会有一些固定的值
重写构造方法的注意点:
1、先调用父类的构造方法(self = [super init])
2、在进行子类内部成员变量的初始化
自定义构造方法:
1、一定是对象方法,一定以-开头
2、返回值一般为id类型
3、方法名一般以init开头
例子:
- (id)initWithName:(NSString*)name;
- (id)initWithName:(NSString*)name
{
if(self = [super init])
{
_name = name;
//如果遇到某些父类的变量为私有变量
[self setName:name];
[super setName:name];
sefl.name=name;
}
return self;
}
调用:Person *p = [[Person alloc] initWithName:@"rose"];
写程序时:能调用原来的程序就不要重复写原来的代码!
谁声明的变量由谁来进行赋值
父类的属性(成员变量)交给父类来处理,子类方法处理子类自己的属性(成员变量)
分类(Category )(类别、类目):
可以给某个类扩充一些方法(不修改原来的代码)
//声明
@interface 类名[分类名称]
@end
//实现
@implementation 类名[分类名称]
@end;
作用:在不改变原来类内容的基础上 可以为类增加一些方法
使用注意:
1、不能扩充成员变量,只能添加方法
2、新增的分类中可以访问成员变量
3、可以直接使用对象调用分类中的方法 分类-原来的类-父类
4、分类的优先级最高,对象调用方法时优先在分类中查找,因此如果分类中重写类中的某个方法,会覆盖掉原来类中的方法,从而导致原来的方法失效
5、方法调用优先级:分类(最后参与编译的分类优先)->原来类->父类
类的本质”
类也是一个对象 是一个class类型的对象 简称类对象
class 类型的定义
typedef struct objc class *class
class 创建 Person类对象
利用Person类对象 创建Person类型的对象
Person *p1 = [[Person alloc] init];
Person *p2 = [[Person alloc] init];
//获取内存中的类对象
class c = [p class];
class c2 = [p2 class];
c 与 c2是相同的
因为p1,p2都是Person类的对象所以内存中的对象类相同
(类对象是否相同可根据对象中的isa的指向进行判断)
另一种获取内存中类对象的方法
class c3 = [Person class];
最终搞得输出结果 c =c2 = c3;
一个类在内存中只有一个存储空间 我们称其为类对象
类的加载顺序:先加载父类 在加载子类
load方法:在类被加载的时候调用 只会被加载一次
initialize方法:当程序启动的时候,会加载一次项目中所有的类,类加载完毕后就会调用load方法
(面试内容)
load方法:程序一启动,加载类的时候被调用,每个类调用一次
initialize方法:第一次用到这个类的时候被调用,总是先调用父类
总结:
1、当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法,只会调用一次、
2、当第一次使用某一个类时,就会调用当前类的+initialize方法
3、先加载父类,在加载子类(先调用父类的+load方法,在调用子类的+load方法)
先初始化父类,在初始化子类(先调用父类的+initialize方法,在调用子类的+initialize方法)
Description:
-description
默认情况下利用NSLog和@输出对象时,结果是<类名:内存地址>
Person *p = [[Person alloc] init];
NSLog(@"%@",p);
执行上述第二句时:
1、会调用对象P的-description方法
2、拿到-description方法的返回值(NSString*)显示到屏幕上
3、-description方法默认返回值是 “类名+内存地址”
因此,要想通过NSLog(@"%@",p)输出p的相关信息就要重写
-description方法
+description:
Class c = [Person class];
NSLog(@"%@",c);
执行上述第二条语句时
1、会调用类的+description方法
2、拿到+description方法的返回值(NSString*)显示到屏幕上
3、+description方法的默认返回值为“类名”
NSLog的扩展输出:
1、NSLog(@"%d",__LINE__);输出当前的行号
//NSLog输出C语言字符串时 不能有中文
2、NSLog(@"%s",__FILE__);输出文件路径(文件路径中不能有中文)
3、NSLog(@"%d",__LINE__);输出当前函数或者方法名
self基本使用:
多种方法调用类中的方法
Person *p = [[Person alloc] init];
[p test2];
执行步骤:
基础:
先利用对象P中的isa指针 到Person类中去寻找 test2方法
而 在Person类中每一个 方法都对应这一个self类的数据(方法的地址)改地址存放于isa指针当中
具体步骤:
1、把test2包装成SEL类型数据
2、去isa中的SEL地址 到Person类中查找对应的方法
3、根据方法地址调用相应的方法
调用方法的两种方法:
1、直接调用
[p test];
第二种 利用SEL=方法名地址
[p performSelector:@selector(test2)];
第三种
每个方法内部都会隐藏一个_cmd 代表当前方法
总结:
SEL其实是对方法的一种包装,将方法包装秤一个SEL类型的数据,去找到相应的方法地址,找到方法地址就可以调用方法
相关文章推荐
- IOS学习---OC基础学习1
- IOS学习---OC基础学习(ARC 协议)
- OC基础:属性.点语法.KVC 分类: ios学习 OC 2015-06-24 17:24 61人阅读 评论(0) 收藏
- ios学习笔记--(oc基础4)
- iOS 阶段学习第11天笔记(OC基础知识)
- IOS学习---OC基础学习2
- OC基础:getter和setter,@public @protected @private 分类: ios学习 OC 2015-06-15 19:23 22人阅读 评论(0) 收藏
- OC基础:内存(内存管理) 分类: ios学习 OC 2015-06-25 16:50 73人阅读 评论(0) 收藏
- OC基础:NSString NSNumber 分类: ios学习 OC 2015-06-17 17:55 77人阅读 评论(0) 收藏
- ios学习笔记--(oc基础3)
- IOS学习---OC基础学习3
- OC基础:类和对象 分类: ios学习 OC 2015-06-12 18:55 17人阅读 评论(0) 收藏
- 黑马程序员-IOS学习笔记-OC基础OC简介及基本语法
- OC基础:内存(进阶):retain.copy.assign的实现原理 分类: ios学习 OC 2015-06-26 17:36 58人阅读 评论(0) 收藏
- IOS学习之路--OC的基础知识
- IOS学习---OC基础学习5
- 黑马程序员——零基础学习iOS开发——10 Object-C 面向对象思想、OC语法简介、对象、类、
- 黑马程序员--IOS入学学习--6-OC基础知识
- ios学习笔记-(oc基础-面向对象小系统)
- OC基础知识总结 分类: ios学习 OC 2015-06-26 17:58 58人阅读 评论(0) 收藏