OC 最重要的语法
来源:互联网 发布:淘宝死人衣服图片 编辑:程序博客网 时间:2024/06/06 13:58
最重要的语法
点语法:
点语法的本质还是方法调用(即指向方法)
不写成员变量,但是写@property的话,那么在@implementation中使用@synthesize的话,访问成员变量,如果不存在的话,就会自动生成@private的成员变量,数据类型根据@property中的数据类型。(这个变量是生成在@implementation中的)
写法:直接写一个@property int age;
这句话将会完成的任务:
1、生成age的get和set方法声明
2、生成一个int类型的成员变量 int _age;(因为生成的变量是@private,所以如果子类需要访问的话,还是需要我们自己写成员变量,这样就不会生成私有的成员变量了)
3、生成age的get和set方法的实现
@synthesize实现
@synthesize age=_age
1、setter和getter实现中会访问成员变量_age;
2、如果成员变量不存在,就会自动生成一个@private的成员变量_age
@synthesize age
1、setter和getter实现中会访问age变量
2、如果成员变量age不存在,就会自动生成一个@private的成员变量age
手动实现
1、若手动实现setter方法,编译器就只会自动生成getter方法
2、若手动实现getter方法,编译器就只会自动生成setter方法
3、若手动同时实现了setter和getter方法,编译器就不会自动生成不存在的成员变量
关键字:id
id是万能指针,能指向\操作任何OC对象
id内部包含*,所以声明变量的时候不需要带 *
NSString * (字符串)也是OC对象,所以id也可以指向字符串
也就是说 id 相当于 NSObject *
id类型的定义:
typedef struct objc object{
Class isa;
} *id;
局限性:
调用一个不存在的方法的时候,编译器会马上报错
构造方法:对象方法
构造方法:用来初始化对象的方法,是个对象方法,以 -号开头
重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
Person *p = [Person new];
new方法完整的创建一个对象(分别调用两个方法完成下面的工作):
1、分配存储空间(+alloc)
2、初始化(-init)
new方法内部进行的工作:
init方法就是构造方法:
等价于:Person *p = [[Person alloc] init];
对象初始化之后,对象的成员变量默认为0
当要求每个Person对象创建出来的时候,他的成员变量_age都是10
构造方法的注意点:
1、先调用父类的构造方法 ([super init])
2、在进行子类内部成员变量的初始化
//重写-init方法
自定义构造函数:
自定义构造函数分两步:
第一步:声明
第二步:实现
自定义构造方法的规范:
1、一定是对象方法,一定以 - 开头
2、返回值一般是id类型
3、方法名一般以initWith开头
声明:
- (id)initWithName:(NSString *)name;
实现:
当子类中的初始化方法需要使用父类的成员变量的时候,原则是:子类中的成员变量在子类中初始化,父类的成员变量在父类中初始化。(父类中提供初始化方法,然后子类将值传递过来)
这样做的好处就是:当父类中的成员变量发生变化的时候,子类不需要更改不会报错。直接改父类就行了
Category:分类
分类:可以给某一个类扩充一些方法(个人理解是修改给已经存在的类添加一些方法)
使用注意:
1、分类只能增加方法,不能增加成员变量
2、分类方法实现中可以访问原来类中声明的成员变量
3、如果分类中的方法与原来类中的方法重名,那么优先调用的是分类中的方法。(这样就会覆盖原来类中的方法,原来类中的方法将不能使用)
4、方法调用的优先级:分类(最后参与编译的分类优先)-->原来类-->父类
characterAtIndex:<#(NSUInteger)#>:字符串的这个方法是获取指定位置上的字符(位置序号从0开始)
类的本质:
1、类也是个对象。简称“类对象”
其实类也是一个对象,是一个Class类型的对象。
Class关键字内部包含 * ,使用的时候后面不需要加 *
利用Person类对象,创建Person类型的对象
//获取内存中的类对象(获取到的类对象可以调用类方法)
Person *p = [[Person alloc] init];
Class c = [p class];
或者:Class c = [Person class];
2、类的加载过程:
+ (void)load:方法,在类被加载的时候调用
程序启动的时候会加载所有的类和分类,并调用所有类和分类的+load方法。
先加载父类,再加载子类,也就是先调用父类的+load,再调用子类的+load。
先加载原始类,再加载分类。
不管程序运行过程中有没有用到这个类,都会调用+load加载。
+initialize
在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法。
一个类只会调用一次+initialize方法,先调用父类的,在调用子类的。
description方法:
-description(决定实例对象的输出结果)
Person *p = [[Person alloc] init];
//默认情况下,利用NSLog和%@输出对象时,结果是: <类名:内存地址>
NSLog(@"%@",p);
打印OC对象使用的占位符是%@
打印OC对象的话(除了NSString *),显示的是类名加上类在内存中的地址
执行NSLog(@"%@",p);这句代码的时候:
1、首先会调用对象p的-description方法
2、拿到-description方法的返回值(NSString *)显示到屏幕上
3、-description方法默认返回的是“类名:内存地址”
当想输出对象的内容的时候,可以在类的实现中重写-description方法:
NSLog():
打印指针中存储的对象的内存地址:
NSLog(@"%p",p);
打印指针变量自己的内存地址:
NSLog(@"%p", &p);
NSLog()输出C语言字符串的时候,不能有中文
NSLog(@"%s",_func_);//输出当前方法名称
NSLog(@"%d",_LINE_);//输出当前行号
NSLog(@"%s",_FILE_);//输出当前源文件的完整路径
NSLog(@"%s",__PRETTY_FUNCTION__ );//返回当前方法或函数的完整的函数名(包括返回值和参数)
SEL类型:
一个类中都有SEL类型数据,一个SEL数据对应一个方法的地址
Person *p = [[Person alloc] init];
[p test2];
1、把test2包装成SEL类型的数据
2、根据SEL数据找到对应的方法地址
3、根据方法地址调用对应的方法(这里使用的缓存技术,第一次会查找,以后就会使用第一次查找的结果)
间接调用test2方法
[p performSelector:@selector(test2)];
方法的存储位置:
每个类的方法列表都存储在类对象中
每个方法都有一个与之对应的SEL类型的数据
根据一个SEL对象就可以找到方法的地址,进而调用
SEL类型的定义
typedef struct objc_selector *SEL;
SEL对象的创建
SEL s=@selector(test);
SEL s2=NSSelectorFormString(@"test");
NSSelectorFormString(@"test");//将一个字符串类型的数据传进去转换成SEL数据
总的来说,OC语言是比较灵活的一门语言。
点语法:
点语法的本质还是方法调用(即指向方法)
Person *p = [Person new]; - (void)setAge:(int)age { _age=age; } - (int)age { return _age; }
不写成员变量,但是写@property的话,那么在@implementation中使用@synthesize的话,访问成员变量,如果不存在的话,就会自动生成@private的成员变量,数据类型根据@property中的数据类型。(这个变量是生成在@implementation中的)
写法:直接写一个@property int age;
这句话将会完成的任务:
1、生成age的get和set方法声明
2、生成一个int类型的成员变量 int _age;(因为生成的变量是@private,所以如果子类需要访问的话,还是需要我们自己写成员变量,这样就不会生成私有的成员变量了)
3、生成age的get和set方法的实现
@synthesize实现
@synthesize age=_age
1、setter和getter实现中会访问成员变量_age;
2、如果成员变量不存在,就会自动生成一个@private的成员变量_age
@synthesize age
1、setter和getter实现中会访问age变量
2、如果成员变量age不存在,就会自动生成一个@private的成员变量age
手动实现
1、若手动实现setter方法,编译器就只会自动生成getter方法
2、若手动实现getter方法,编译器就只会自动生成setter方法
3、若手动同时实现了setter和getter方法,编译器就不会自动生成不存在的成员变量
关键字:id
id是万能指针,能指向\操作任何OC对象
id内部包含*,所以声明变量的时候不需要带 *
NSString * (字符串)也是OC对象,所以id也可以指向字符串
也就是说 id 相当于 NSObject *
id类型的定义:
typedef struct objc object{
Class isa;
} *id;
局限性:
调用一个不存在的方法的时候,编译器会马上报错
构造方法:对象方法
构造方法:用来初始化对象的方法,是个对象方法,以 -号开头
重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
Person *p = [Person new];
new方法完整的创建一个对象(分别调用两个方法完成下面的工作):
1、分配存储空间(+alloc)
2、初始化(-init)
new方法内部进行的工作:
//调用+alloc方法分配存储空间 Person *p1 = [Person alloc]; //调用-init方法进行初始化 Person *p2 = [p1 init];
init方法就是构造方法:
等价于:Person *p = [[Person alloc] init];
对象初始化之后,对象的成员变量默认为0
当要求每个Person对象创建出来的时候,他的成员变量_age都是10
构造方法的注意点:
1、先调用父类的构造方法 ([super init])
2、在进行子类内部成员变量的初始化
//重写-init方法
- (id)init { //1、一定要调用super的init方法:初始化父类中声明的一些成员变量和其他属性 //2、如果父类初始化成功,才有必要进行接下来的初始化 if (self = [super init]) { //初始化成功 _age = 10; } //3、返回一个已经初始化完毕的对象 return self; }
自定义构造函数:
自定义构造函数分两步:
第一步:声明
第二步:实现
自定义构造方法的规范:
1、一定是对象方法,一定以 - 开头
2、返回值一般是id类型
3、方法名一般以initWith开头
声明:
- (id)initWithName:(NSString *)name;
实现:
- (id)initWithName:(NSString *)name { if(self = [super init]) { _name=name; } return self; }
当子类中的初始化方法需要使用父类的成员变量的时候,原则是:子类中的成员变量在子类中初始化,父类的成员变量在父类中初始化。(父类中提供初始化方法,然后子类将值传递过来)
这样做的好处就是:当父类中的成员变量发生变化的时候,子类不需要更改不会报错。直接改父类就行了
Category:分类
分类:可以给某一个类扩充一些方法(个人理解是修改给已经存在的类添加一些方法)
//声明 @interface 类名 (分类名称) @end //实现 @implementaion 类名 (分类名称) @end
使用注意:
1、分类只能增加方法,不能增加成员变量
2、分类方法实现中可以访问原来类中声明的成员变量
3、如果分类中的方法与原来类中的方法重名,那么优先调用的是分类中的方法。(这样就会覆盖原来类中的方法,原来类中的方法将不能使用)
4、方法调用的优先级:分类(最后参与编译的分类优先)-->原来类-->父类
characterAtIndex:<#(NSUInteger)#>:字符串的这个方法是获取指定位置上的字符(位置序号从0开始)
类的本质:
1、类也是个对象。简称“类对象”
其实类也是一个对象,是一个Class类型的对象。
Class关键字内部包含 * ,使用的时候后面不需要加 *
利用Person类对象,创建Person类型的对象
//获取内存中的类对象(获取到的类对象可以调用类方法)
Person *p = [[Person alloc] init];
Class c = [p class];
或者:Class c = [Person class];
2、类的加载过程:
+ (void)load:方法,在类被加载的时候调用
程序启动的时候会加载所有的类和分类,并调用所有类和分类的+load方法。
先加载父类,再加载子类,也就是先调用父类的+load,再调用子类的+load。
先加载原始类,再加载分类。
不管程序运行过程中有没有用到这个类,都会调用+load加载。
+initialize
在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法。
一个类只会调用一次+initialize方法,先调用父类的,在调用子类的。
description方法:
-description(决定实例对象的输出结果)
Person *p = [[Person alloc] init];
//默认情况下,利用NSLog和%@输出对象时,结果是: <类名:内存地址>
NSLog(@"%@",p);
打印OC对象使用的占位符是%@
打印OC对象的话(除了NSString *),显示的是类名加上类在内存中的地址
执行NSLog(@"%@",p);这句代码的时候:
1、首先会调用对象p的-description方法
2、拿到-description方法的返回值(NSString *)显示到屏幕上
3、-description方法默认返回的是“类名:内存地址”
当想输出对象的内容的时候,可以在类的实现中重写-description方法:
- (NSString *)description { return [NSString stringWithFormat:@"age=%d,name=%@",_age,_name]; } //不要在description中尝试输出self:NSLog(@"%@",self),这样会引发死循环 // +description(决定类对象的输出结果) Class c = [Person class]; //会调用类的+description方法 //拿到+description方法的返回值(NSString *)显示到屏幕上(默认返回的是类名) NSLog(@"%@",c);
NSLog():
打印指针中存储的对象的内存地址:
NSLog(@"%p",p);
打印指针变量自己的内存地址:
NSLog(@"%p", &p);
NSLog()输出C语言字符串的时候,不能有中文
NSLog(@"%s",_func_);//输出当前方法名称
NSLog(@"%d",_LINE_);//输出当前行号
NSLog(@"%s",_FILE_);//输出当前源文件的完整路径
NSLog(@"%s",__PRETTY_FUNCTION__ );//返回当前方法或函数的完整的函数名(包括返回值和参数)
SEL类型:
一个类中都有SEL类型数据,一个SEL数据对应一个方法的地址
Person *p = [[Person alloc] init];
[p test2];
1、把test2包装成SEL类型的数据
2、根据SEL数据找到对应的方法地址
3、根据方法地址调用对应的方法(这里使用的缓存技术,第一次会查找,以后就会使用第一次查找的结果)
间接调用test2方法
[p performSelector:@selector(test2)];
方法的存储位置:
每个类的方法列表都存储在类对象中
每个方法都有一个与之对应的SEL类型的数据
根据一个SEL对象就可以找到方法的地址,进而调用
SEL类型的定义
typedef struct objc_selector *SEL;
SEL对象的创建
SEL s=@selector(test);
SEL s2=NSSelectorFormString(@"test");
NSSelectorFormString(@"test");//将一个字符串类型的数据传进去转换成SEL数据
总的来说,OC语言是比较灵活的一门语言。
0 0
- OC 最重要的语法
- OC的语法简写
- OC的点语法
- OC的语法简写
- OC语法的核心
- OC的链式语法
- 关于OC 特有的语法
- oc的点语法详解
- OC点语法的使用
- OC语法<3.1> OC中特有的语法:Category分类
- OC语法<3.2> OC中特有的语法:Block数据类型
- OC语法<3.3> OC中特有的语法:Protocol协议
- OC-语法
- OC语法
- OC语法
- OC语法
- OC学习笔记之OC的核心语法
- iOS OC语言(一)语法简介 , OC 的特点
- ubantu 12.4 enable fastboot devices to avoid no permission
- 正则表达式中括号的用法
- 我所认识的GNU make(2) -- make规则
- Django如何更新数据库
- 分治算法
- OC 最重要的语法
- 简介
- socket tcp 链接状态
- oc的语法基础(一)
- C++标准库---已序算法之三合并元素
- Android中如何判断是手机还是平板
- Android:shape属性详解(图文并茂)
- 黑马程序员,Java基础知识八:IO流
- HDU 5151Sit sit sit