oc学习笔记(七)面向对象-核心语法
2014-05-27 20:31
134 查看
一、点语法
1.可以让其它程序员很容易上手能看懂oc语言
点语法的本质还是方法调用(本质是get或者set方法)
//编译器会自动把点语法,转换成相应的方法
Person *p = [Person new]; //转成set方法 [p setAge:10];
int a= p.age; //转成get方法 [p age];
2.在set和get方法种如下使用可引发死循环
- (void)setAge:(int)age
{
//_age = age;
NSLog(@"age");
//会引发死循环
self.age = age ; // 相当于[self setAge:age];
}
- (int)age
{
NSLog(@"age");
//return _age;
//会引发死循环
return self.age; // 相当于[self age];
}
二、成员变量的作用域
三、oc中是单继承
四、@property:自动生成某个成员变量的get和set方法的声明
原理:编译器特性,在编译的时候会自动转换成getter和setter
注意:可连写
2.@synthesize 自动生成setter 和getter的实现。
注意1>:还可以连写,看下面代码示例
应该写
3.@synthesize 在生成getter和setter的实现时,如果成员变量不存在,就会自动生成
//@synthesize speed = _speed, wheels = _wheels;
// 会访问_speed这个成员变量,如果不存在,就会自动生成@private类型的_speed变量
4.在xcode4.4之后,如果不存在成员变量和方法的 实现
只需要写@property int age 这样的声明
就会自动生成@private类型的成员变量,和生成实现的方法
所以,@property独揽了声明和实现的功能,(如果没有写就会自动生成,如果已经存在就不会再生成了。)
五、id 关键字
// id == NSObject *
//
万能指针,能指向\操作任何OC对象
id d = [Person new];
六、构造方法
// 构造方法:用来初始化对象的方法,是个对象方法,-开头
// 重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
/*
重写构造方法的注意点
1.先调用父类的构造方法([super init])
2.再进行子类内部成员变量的初始化
*/
1.完整地创建一个可用的对象分两步
1.分配存储空间 +alloc
2.初始化 -init
// Person *p = [Person new];
// 1.调用+alloc分配存储空间
// Person *p1 = [Person alloc];
// 2.调用-init进行初始化
// Person *p2 = [p1 init];
2.等于如下方式,以后要按如下来书写
Person *p4 = [[Person alloc] init];
3.重写构造方法步骤如下:
在.m文件中
4.自定义构造方法
/*
自定义构造方法的规范
1.一定是对象方法,一定以 -开头
2.返回值一般是id类型
3.方法名一般以initWith开头
*/
- (id)initWithName:(NSString *)name;
使用的时候,可以在定义变量的时候直接调用
Student *p = [[Student alloc] initWithName:@"Jim" andAge:29 andNo:10];
七、分类- Category
l 继承
l 分类(Category)
@interface 类名 (分类名称)
// 方法声明
@end
Ø 分类的实现
@implementation 类名 (分类名称)
// 方法实现
@end
Ø 一个庞大的类可以由多个人来编写,更有利于团队合作
1.分类的作用:在不改变原来类内容的基础上,可以为类增加一些方法
使用注意:
1.分类只能增加方法,不能增加成员变量
2.分类方法实现中可以访问原来类中声明的成员变量
3.分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用(不建议这样用)
4.方法调用的优先级:分类(最后参与编译的分类优先) -->原来类 -->父类
2.开发过程中经常是给系统自带的类,扩充分类
举例:
八、类的本质
1.类本身也是一个对象,是个Class类型的对象,简称类对象
Person *p = [[Person alloc] init]对象创建过程:
>1,利用Class 创建 Person类对象
>2,利用 Person类对象 创建 Person类型的对象
2.获取内存中的的类对象2种方法
>1.调用某个对象的某个对象方法(这里是class方法)
如下图中p对象中是有class方法的
Class c = [p class]; //c为类对象
》2.第二种方式:
通过这个类的类方法
Class c3 = [Person class]
3.类可以做一个事情:
类可以调用类方法。
Class c = [Person class];
Person *p2 = [c new];
4.类的本质之类的加载
1.当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法。只会调用一次。
2.当第一次使用某个类时,就会调用当前类的+initialize方法
3.先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)
先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)//如果类中有分类,分类优先级高会覆盖原类。
代码示例如下
// 当程序启动的时候,就会加载一次项目中所有的类。类加载完毕后就会调用+load方法
+ (void)load
{
NSLog(@"Person---load");
}
// 当第一次使用这个类的时候,就会调用一次+initialize方法
+ (void)initialize
{
NSLog(@"Person-initialize");
}
九、description方法
1. 对象占位符都是%@
2. +description方法
Class c = [Person class];
// 1.会调用类的+description方法
// 2.拿到+description方法的返回值(NSString *)显示到屏幕上
/ / 3.默认输出结果是:类名
NSLog(@"%@", c);
--------------------
3.-description方法
Person *p = [[Person alloc] init];
p.age =
20;
p.name =
@"Jack";
//默认情况下,利用NSLog和%@输出对象时,结果是:<类名:内存地址>
// 1.会调用对象p的-description方法
// 2.拿到-description方法的返回值(NSString *)显示到屏幕上
// 3.-description方法默认返回的是“类名+内存地址”
NSLog(@"%@", p);
十、NSLog 增强,输出补充。
void test9()
{
//
输出当前函数名
NSLog(@"%s\n", __func__);
}
int main()
{
//
输出行号
NSLog(@"%d", __LINE__);
// NSLog输出C语言字符串的时候,不能有中文
// NSLog(@"%s", __FILE__);
//输出源文件的名称
printf("%s\n", __FILE__);
test9();
return 0;
}
十一、SEL 类型
在对象调用方法的时候,把方法包装成SEL类型,去类中查找。
第二次查找时会直接使用之前查找的结果缓存;
经典错误中找不到方法的selector就是这种消息,sel是简称。
内存表示如下:
代码如下:
下方[p performSelector:@selector(test3:) withObject:@"456"]这句中test3方法一定要加冒号(方法名都要加上:)
否刚会报经典错误,如下:
Ø 每个方法都有一个与之对应的SEL类型的对象
Ø 根据一个SEL对象就可以找到方法的地址,进而调用方法
Ø SEL类型的定义
typedef
struct objc_selector *SEL;
@selector(test);
SEL s2 = NSSelectorFromString(@"test");
NSString*str =
NSStringFromSelector(@selector(test));
Person *p= [Person new];
//调用对象p的test方法
[p performSelector:@selector(test)];
4. 每个方法里面都有 SEL类型的 _cmd 代表者当前方法
NSString*str = [p
performSelector:@selector(_cmd)];
取出方法名
1.可以让其它程序员很容易上手能看懂oc语言
点语法的本质还是方法调用(本质是get或者set方法)
//编译器会自动把点语法,转换成相应的方法
Person *p = [Person new]; //转成set方法 [p setAge:10];
int a= p.age; //转成get方法 [p age];
2.在set和get方法种如下使用可引发死循环
- (void)setAge:(int)age
{
//_age = age;
NSLog(@"age");
//会引发死循环
self.age = age ; // 相当于[self setAge:age];
}
- (int)age
{
NSLog(@"age");
//return _age;
//会引发死循环
return self.age; // 相当于[self age];
}
二、成员变量的作用域
/* @public : 在任何地方都能直接访问对象的成员变量 @private : 只能在当前类的对象方法中直接访问(@implementation中默认是@private) @protected : 可以在当前类及其子类的对象方法中直接访问 (@interface中默认就是@protected) @package : 只要处在同一个框架中,就能直接访问对象的成员变量 @interface和@implementation中不能声明同名的成员变量 */ #import <Foundation/Foundation.h> @interface Person : NSObject { int _no; @public // 在任何地方都能直接访问对象的成员变量 int _age; @private // 只能在当前类的对象方法中直接访问 int _height; @protected // 能在当前类和子类的对象方法中直接访问 int _weight; int _money; } - (void)setHeight:(int)height; - (int)height; - (void)test; @end
三、oc中是单继承
四、@property:自动生成某个成员变量的get和set方法的声明
原理:编译器特性,在编译的时候会自动转换成getter和setter
注意:可连写
@property int age, height;
#import <Foundation/Foundation.h> @interface Person : NSObject { int _age; // int age; int _height; double _weight; NSString *_name; } // @property:可以自动生成某个成员变量的setter和getter声明 @property int age; //- (void)setAge:(int)age; //- (int)age; @property int height; //- (void)setHeight:(int)height; //- (int)height; - (void)test; @property double weight; @property NSString *name; @end
2.@synthesize 自动生成setter 和getter的实现。
注意1>:还可以连写,看下面代码示例
@synthesize weight = _weight, name = _name;注意2>:
@synthesize age;默认是访问 age ,相当于 @synthesize age=age
应该写
@synthesize age = _age;
#import "Person.h" @implementation Person // @synthesize自动生成age的setter和getter实现,并且会访问_age这个成员变量 @synthesize age = _age; // -(void)setAge:(int)age //{ // _age = age; //} // - (int)age //{ // return _age; //} @synthesize height = _height; @synthesize weight = _weight, name = _name;//还可以连写 @end
3.@synthesize 在生成getter和setter的实现时,如果成员变量不存在,就会自动生成
//@synthesize speed = _speed, wheels = _wheels;
// 会访问_speed这个成员变量,如果不存在,就会自动生成@private类型的_speed变量
4.在xcode4.4之后,如果不存在成员变量和方法的 实现
只需要写@property int age 这样的声明
就会自动生成@private类型的成员变量,和生成实现的方法
所以,@property独揽了声明和实现的功能,(如果没有写就会自动生成,如果已经存在就不会再生成了。)
五、id 关键字
// id == NSObject *
//
万能指针,能指向\操作任何OC对象
id d = [Person new];
六、构造方法
// 构造方法:用来初始化对象的方法,是个对象方法,-开头
// 重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
/*
重写构造方法的注意点
1.先调用父类的构造方法([super init])
2.再进行子类内部成员变量的初始化
*/
1.完整地创建一个可用的对象分两步
1.分配存储空间 +alloc
2.初始化 -init
// Person *p = [Person new];
// 1.调用+alloc分配存储空间
// Person *p1 = [Person alloc];
// 2.调用-init进行初始化
// Person *p2 = [p1 init];
2.等于如下方式,以后要按如下来书写
Person *p4 = [[Person alloc] init];
3.重写构造方法步骤如下:
在.m文件中
// // Person.m // 02-构造方法 // // Created by apple on 13-8-8. // Copyright (c) 2013年 itcast. All rights reserved. // #import "Person.h" @implementation Person // 重写-init方法 //- (id)init //{ // // 1.一定要调用回super的init方法:初始化父类中声明的一些成员变量和其他属性 // self = [super init]; // 当前对象 self // // // // 2.如果对象初始化成功,才有必要进行接下来的初始化 // if (self != nil) // { // 初始化成功 // _age = 10; // } // // // 3.返回一个已经初始化完毕的对象 // return self; //} //简写为如下: - (id)init { if ( self = [super init] ) { // 初始化成功 _age = 10; } // 3.返回一个已经初始化完毕的对象 return self; } @end
4.自定义构造方法
/*
自定义构造方法的规范
1.一定是对象方法,一定以 -开头
2.返回值一般是id类型
3.方法名一般以initWith开头
*/
- (id)initWithName:(NSString *)name;
使用的时候,可以在定义变量的时候直接调用
Student *p = [[Student alloc] initWithName:@"Jim" andAge:29 andNo:10];
七、分类- Category
1. 基本用途
Ø 如何在不改变原来类模型的前提下,给类扩充一些方法?有2种方式l 继承
l 分类(Category)
2. 格式
Ø 分类的声明@interface 类名 (分类名称)
// 方法声明
@end
Ø 分类的实现
@implementation 类名 (分类名称)
// 方法实现
@end
3. 好处
Ø 一个庞大的类可以分模块开发 (使用模块名命名)Ø 一个庞大的类可以由多个人来编写,更有利于团队合作
1.分类的作用:在不改变原来类内容的基础上,可以为类增加一些方法
使用注意:
1.分类只能增加方法,不能增加成员变量
2.分类方法实现中可以访问原来类中声明的成员变量
3.分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用(不建议这样用)
4.方法调用的优先级:分类(最后参与编译的分类优先) -->原来类 -->父类
2.开发过程中经常是给系统自带的类,扩充分类
举例:
// // NSString+Number.m // 05-分类的应用 // // Created by apple on 13-8-8. // Copyright (c) 2013年 itcast. All rights reserved. // #import "NSString+Number.h" @implementation NSString (Number) // @"abc434ab43" + (int)numberCountOfString:(NSString *)str { // 1.定义变量计算数字的个数 // int count = 0; // // for (int i = 0; i<str.length; i++) // { // unichar c = [str characterAtIndex:i]; // // if ( c>='0' && c<='9') // { // count++; // } // } // return count; return [str numberCount]; } - (int)numberCount { int count = 0; for (int i = 0; i<self.length; i++) { // 取出i这个位置对应的字符 unichar c = [self characterAtIndex:i]; // 如果这个字符是阿拉伯数字 if ( c>='0' && c<='9' ) { count++; } } return count; } @end
八、类的本质
1.类本身也是一个对象,是个Class类型的对象,简称类对象
Person *p = [[Person alloc] init]对象创建过程:
>1,利用Class 创建 Person类对象
>2,利用 Person类对象 创建 Person类型的对象
2.获取内存中的的类对象2种方法
>1.调用某个对象的某个对象方法(这里是class方法)
如下图中p对象中是有class方法的
Class c = [p class]; //c为类对象
》2.第二种方式:
通过这个类的类方法
Class c3 = [Person class]
3.类可以做一个事情:
类可以调用类方法。
Class c = [Person class];
Person *p2 = [c new];
4.类的本质之类的加载
1.当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法。只会调用一次。
2.当第一次使用某个类时,就会调用当前类的+initialize方法
3.先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)
先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)//如果类中有分类,分类优先级高会覆盖原类。
代码示例如下
// 当程序启动的时候,就会加载一次项目中所有的类。类加载完毕后就会调用+load方法
+ (void)load
{
NSLog(@"Person---load");
}
// 当第一次使用这个类的时候,就会调用一次+initialize方法
+ (void)initialize
{
NSLog(@"Person-initialize");
}
九、description方法
1. 对象占位符都是%@
2. +description方法
Class c = [Person class];
// 1.会调用类的+description方法
// 2.拿到+description方法的返回值(NSString *)显示到屏幕上
/ / 3.默认输出结果是:类名
NSLog(@"%@", c);
--------------------
3.-description方法
Person *p = [[Person alloc] init];
p.age =
20;
p.name =
@"Jack";
//默认情况下,利用NSLog和%@输出对象时,结果是:<类名:内存地址>
// 1.会调用对象p的-description方法
// 2.拿到-description方法的返回值(NSString *)显示到屏幕上
// 3.-description方法默认返回的是“类名+内存地址”
NSLog(@"%@", p);
十、NSLog 增强,输出补充。
void test9()
{
//
输出当前函数名
NSLog(@"%s\n", __func__);
}
int main()
{
//
输出行号
NSLog(@"%d", __LINE__);
// NSLog输出C语言字符串的时候,不能有中文
// NSLog(@"%s", __FILE__);
//输出源文件的名称
printf("%s\n", __FILE__);
test9();
return 0;
}
十一、SEL 类型
在对象调用方法的时候,把方法包装成SEL类型,去类中查找。
第二次查找时会直接使用之前查找的结果缓存;
经典错误中找不到方法的selector就是这种消息,sel是简称。
内存表示如下:
代码如下:
下方[p performSelector:@selector(test3:) withObject:@"456"]这句中test3方法一定要加冒号(方法名都要加上:)
否刚会报经典错误,如下:
1. 方法的存储位置
Ø 每个类的方法列表都存储在类对象中Ø 每个方法都有一个与之对应的SEL类型的对象
Ø 根据一个SEL对象就可以找到方法的地址,进而调用方法
Ø SEL类型的定义
typedef
struct objc_selector *SEL;
2. SEL对象的创建
SEL s =@selector(test);
SEL s2 = NSSelectorFromString(@"test");
3. SEL对象的其他用法
// 将SEL对象转为NSString对象NSString*str =
NSStringFromSelector(@selector(test));
Person *p= [Person new];
//调用对象p的test方法
[p performSelector:@selector(test)];
4. 每个方法里面都有 SEL类型的 _cmd 代表者当前方法
NSString*str = [p
performSelector:@selector(_cmd)];
取出方法名
相关文章推荐
- 黑马程序员-iOS学习日记(七)面向对象-核心语法(二)
- 黑马程序员——OC学习笔记04 核心语法
- 黑马程序员_OC面向对象之核心语法
- 黑马程序员--ios基础--oc--面向对象--核心语法
- 黑马程序员-iOS学习日记(六)面向对象-核心语法(一)
- [php入门] 2、基础核心语法大纲
- .NET程序员新方向 Ruby核心语法入门
- Java核心技术——Java语法和数据类型
- C#编程语言与面向对象——核心
- 黑马程序员—(iOS开发)OC开发技巧及核心语法---(九)
- OC 核心语法
- 【黑马程序员】Objective-C语言学习笔记之核心语法(四)
- OC学习笔记二(点语法)
- 黑马程序员——OC核心语法3(分类、SEL、类本质等)
- C++开发者快速学习Objective-C语言核心语法
- 【Objective-C学习笔记】核心语法——类的本质、description方法
- 学习笔记:OC核心语法
- XAML开发入门之XAML核心语法
- Scrapy官网tutorial、Requests官网文档、lxml官方文档、XPath语法、python核心模块pickle和cPickle讲解