- 定义类:
@interface 类名 : 父类
@end
- 使用:(冒号)表示继承一个类
Student : NSObject
- 使用()定义一个Catagory(类别)
- 作用:在不改变原有类结构的基础上,扩展原有类的方法(不能扩展属性),但不建议重载原有类的方法
- 开发工具默认生成的文件为:类名+Catagory名称
- Catagory可以写在单独的文件中,也可以写在原有类的文件中,如何写根据需求来决定。
- 使用<>表示实现一个Protocol(协议),如需实现多个协议,将协议名以逗号分隔都写在括号中即可
*可以理解为java中的接口,但不同的是,实现类编译器不强制实现Protocol中定义的所有接口
- 在方法签名上标识:@required,从字面上理解实现类必须实现该方法,其实写与不写一样的效果。也是默认的
- 在方法签名上标识:@optional,表示实现类对该方法的实现,是可选的。
- 属性的访问权限
- private : 只有类内部可以访问
- protected : 类内部和子类可以访问(默认)
- public : 访问没有限制
例:
// 定义
@interface Student : NSObject {
@private int _age;
@protected int _no;
@public float _height;
}
@end
// 使用
Student *stu = [[[Student alloc]init]autorelease];
stu->_height = 20;// 直接读写属性的值,开发当中一般不建议这么做。违背了面向对象的开发原则-》封装性
- 属性的定义与封装
// in Student.h
@interface Student : NSObject {
// 1. 定义属性,默认访问权限是@protected的,只有自已和子类可以直接访问
int _age;// OC语法中建议属性名前面加上下划线,以和参数名区分
int _no;
}
// 2.提供属性对外读写方法的声明,供外界调用。OC创建属性读写方法的命名规则是为,set方法: set+属性名,get方法:属性名
// 声明age的get和set方法
- (int)age;
- (void)setAge:(int)age;
// 声明no的get和set方法
- (int)no;
- (void)setNo:(int)no;
@end
// in Student.m 实现头文件中的方法
#import "Student.h"// 导入头文件
@implementation Student
// 实现头文件中的方法
- (int)age { // age的getter方法
return _age;
}
- (void)setAge:(int)age {// age的setter方法
_age = age;
}
- (int)no {
return _no;
}
- (void)setNo:(int)no {
_no = no;
}
@end
- 使用@synthesize自动生成属性getter和setter方法的实现,同时会生成一个下划线(_)+属性名的成员变量。需要和@property配合使用。例:
@implementation Student
@synthesize age;// 这一句顶下面的get和set方法,由@synthesize自动生成
- (int)age { // age的getter方法
return _age;
}
- (void)setAge:(int)age {// age的setter方法
_age = age;
}
@end
注:在xcode4.5以后的编译环境中,不需要写@synthesize声明生成属性的get和set方法实现。只需要在头文件中用@property定义即可自动在.m文件中生成相应属性的get和set方法实现
- 使用@property声明一个属性,编译器会自动生成该属性的getter和setter方法的声明
在xcode4.5以后版本的编译器环境中,会自动在.m文件中生成该属性getter和setter方法的标准实现,不需显示声明用@synthesize来生成属性的getter和setter方法实现。
- @property属性参数
1> nonatomic : 多线程环境下,不需要线程保护(读写时不加锁),
atomic : (默认)多线程环境下需要线程保护(读写时加锁).
2> readonly : 表示在.m文件中只生成属性的getter方法的实现
readwriter : 表示在.m文件中生成属性的getter和setter方法的实现(默认)
3> retain : 表示调用该属性的setter方法时,先release旧的值,再retain新的值。一般声明的成员变量是NSObject的子类才会添加该参数
assign : 生成标准的getter和setter方法实现(默认),直接给属性赋值
4> getter= : 表示自定义属性生成的getter方法名称
setter= : 表示自定义属性生成的setter方法名称
- 方法调用
- [实例对象 方法名:参数列表]
- [类名 方法名:参数列表]
例:
Student *stu = [[[Student alloc]init]autorelease];
[stu setAge:22 andNo:10];// 调用实例方法
[Student initWithAge:20];// 调用静态方法
- 点(.)语法
Student *stu = [[[Student alloc]init]autorelease];
stu.age = 20; // 相当于调用了对象的setAge方法(写)
int age = stu.age;// 相当于调用了对象的getAge方法(读)
- self关键字
相当于java中的this,不同的是self在不同的环境下,作用也不同。在实例方法中self可以当该对象使用,在静态方法中,self可以当类对象使用。
如:
- (void)age {
return self.age;// 这里self是实例对象本身
}
+ (id)newInstace {
//Student *stu = [[[Student alloc]init]autorelease];
Student *stu = [[[self alloc]init]autorelease];// 这一句和上一句代码的效果是等效的,而在java语法是不允许this出现在静态方法中的
return stu;
}
- @class : 在头文件中声明一个类的存在
为了提高效率,在只需要知道类的存在的情况下,不需要导入某个类的头文件。
// #import "Book.h"
@class Book; // 不需要导入Book.h头文件,在.m文件真正使用的时候再导入
@interface Student : NSObject
@property Book *book;
@end
@protocol : 在头文件中声明一个协议的存在
目的和@class一样^ : 定义一个Block类型,与标准C语法中指向函数指针类型的写法非常相似
如:定义一个sum的Block类型,返回值为int,有两个int形参
int (^sum) (int, int) = ^(int a, int b) {
return a + b;
};
import : 用于导入一个类的头文件
#pragma mark : 写方法的注释
#pragma mark - : 方法注释分组
+ : 声明或定义一个静态方法
- : 声明或定义一个实例方法
- 方法定义(一个冒号代表一个参数,冒号也是属性方法的一部份)
方法类型 (返回值类型)方法名称[参数列表] {(一个冒号代表一个参数,冒号也是属性方法的一部份)
// 方法体
}
// 实例方法,方法名: sumAge:andNo:
- (int)setAge:(int)age andNo:(int)no {
// 在这里插入代码逻辑
}
// 静态方法
+ (id)initWithAge:(int)age {
// 在这里插入代码逻辑
}
注:
* 实例方法通过类的实例对象访问
* 静态方法通过类名或self访问
- 内存管理
1> 凡是从NSObject中继承的类都需要自己管理内存,在OC语法中,创建的任何一个对象都拥有一个引用计数器,第一次创建的时候这个引用计数器为1,当引用计数器的值为0时,该对象会被销毁。内存管理涉及到以下接口:
- release : 对象的引用计数器减1
- retain : 对象的引用计数器加1
- retainCount : 获取对象当前引用计数器的数量
对象生命周期回调接口: - init : 对象的默认构造方法,如果自定义构造方法用于初始化成员变量时,必须先调用父类的构造方法,并判断获得的对象是否为nil,再初始化成员变量。
如:
- (void)initWithAge:(int)age {
if ( self = [super init] ) {
_age = age;
}
return self;
}
- dealloc : 对象销毁时,系统会自动调用该方法,通常在该方法中释放内存或其它资源。在重写dealloc方法时,注意在代码最后面调用父类的dealloc方法,用于释放内存等相关资源。
如:
- (void)dealloc {
[_book release];// 释放成员变量
[super dealloc];
}
2> 不需要管理内存的对象
- 基本数据类型
- 系统自带的类调用自己的静态方法创建的对象,是自动释放内存的,不需要管理
3> 内存管理原则
只有向对象发送了alloc,retain,copy,new消息才有必要做release操作
- 谁alloc,retain,copy,new谁release
- 谁创建谁释放(release)
- 谁没有allock,retain,copy,new,你就不要做release操作
4> 自动内存管理(由autoreleasepool管理)
在创建对象的同时,调用autorelease方法,会将该对象的一个 引用自动存放到最近创建的一个自动释放释放池中。以后该对象就不需要手动来release操作,徐非做了retain,copy等修改了引用计数器的操 作。当自动释放池被销毁时,会向池子中所有对象发送一个release消息,池子中的所有对象的引用计数器此时会减1,只有当池子中的引用计数器为0时, 该对象才会被彻底销毁。不是说只要将对象交给自动释放池了,池子被销毁,池子中的所有对象就一定会被销毁。
如:
@autoreleasepool {
Student *stu = [[[Student alloc] init]autorelease];// 此时stu对象将放到这个大括号中的自动释放池子中
[stu retain];
// 如果加了这一句,此时stu的引用计数器为2,这时候如果在池子销毁前没有向对象发送release消息,就算池子销毁,该对象也还是会造成内存泄露
} // 程序执行到此处,代表自动释放池被销毁,意味着池子中的所有对象都会接到一个release消息
- OC中的类似Java的toString方法
Student *stu = [[[Student alloc]init]autorelease];
NSLog(@"%@",stu);// 默认打印的是stu对象的内存地址
- 重写父类的description方法,可自定义打印对象的信息
- (NSString *)description {
NSLog(@"age is %i",_age);
}