在OC中有个分类的功能,C++中没有,分类可以很好地在类中添加新的方法,而不是用继承来实现。
分类的固定框架:
类名+增加函数名.m,与类实现函数放在同一个目录下面,在分类函数中@interface 类名(新增函数名)
OC中分类是如何实现的?
分类的使用是通过Objective-C的动态绑定实现,通过分类能够实现比继承更好的效果,通过category不能添加新的实例变量
OC 中的动态类型检查和静态类型检查
静态类型检查是指在程序编译期间,编译器会会检查该类型是否有对应的方法。
动态类型检查是指指使用好几种不同的方式指向同一个类型。
sample:
NSArray *array=[NSMutableArrayarray];
[array addObject:@"hello"];
上面这段代码在运行时是正常的,但在编译期间会有warning,因为NSArray没有addObject函数NSMutableArray *mutableArray=[NSMutableArrayarray];
NSArray *array=[NSArrayarray];
mutableArray=array;
[mutableArray addObject:@"hello"];
上面这段代码编译会有warning, 但在执行时出错
在XCode中可以设置xcode ,将警告当做错误对待
类方法前面有+,实例方法前面有-
类方法和实例方法的区别在于,类方法不能使用实例变量。
使用类方法主要原因有:
1.类方法的使用不依赖于实例化一个对象,也就是说如果一个功能的实现不需要实例化对象,就可以用类方法来实现。
2.类方法可以隐藏单例,将类方法和单例结合,可以在应用程序的任何地方访问静态实例,而无需使用指向对象的指针或保存他的实例变量。
3.类方法和内存管理相关,分配一个NSArray,可以【NSArray alloc】init,也可以【NSArray array】,但是前者必须释放,而后者返回一个随时准备好自动释放的数组对象,并不需要你进行release操作
OC中常用的for/in 方法实现
int main(int argc, const char * argv[])
{
NSArray *colors=[NSArrayarrayWithObjects:@"hello",@"richard",@"yang",nil];
for(NSString *strin colors)
{
NSLog(@"the val is %s",[strUTF8String]);
}
return 0;
}
第一、关于super
向super发送信息时,实际上是请求Objectiv-c向该类的超类发送消息,如果超类没有定义该消息,objective-c将按照通常的方式在继承链中继续查找对应的消息
第二、关于继承的实例变量
创建一个新类时,其对象首先从其自身的超类继承实例变量,然后再添加自己的实例变量,由于类的基类是NSObject,所以每个类最前面都是isa指针,代表NSObject的实例变量。
第三、lazy evaluation(惰性求值)
在init函数中没有进行创建,当在使用时先判断是否为空,如果为空则创建,这样会节省内存,提高效率
第四、关于属性
利用属性可以减少需要编写的代码,使用@property预编译指令可以通知编译器,该变量具有的特征:可读、可写、对象的内存管理、并发性,此外编译器应该自动生成set方法和get方法。
在xcode4.2版本的编译器上,@property声明的变量,前面加下划线的变量就是私有变量,在_init函数中直接操作该变量,在dealloc函数中一定要release,如果该变量在init函数中没有初始化,也应该release,因为对于nil变量执行release是不会报错的
第五、关于循环引用的问题
A引用B,B引用A,在A的dealloc函数中先要释放B的对象才能【super dealloc】,在B的dealloc函数中先要释放A的对象才能【super dealloc】,陷入死循环。
解除死循环的方法,在B中定义A的变量时为assign
sample code:
- (void)setC:(C *)c
{
if (_c != c) {
[_c release];
_c = [c retain];
}
}
- (void)setB:(B *)b
{
if (_b != b) {
[_b release];
_b = [b retain];
}
}
B *b = [[B alloc] init]; // 1
C *c = [[C alloc] init]; // 1
[b setC:c]; // c : 2
NSLog(@"c retaincount is %lu",[c retainCount]);
[c setB:b];
NSLog(@"b retaincount is %lu",[b retainCount]);
[c release];
[b release];
NSLog(@"c retaincount is %lu",[c retainCount]);
NSLog(@"b retaincount is %lu",[b retainCount]);
result:
RetainCycle[1102:303] c retaincount is 2
2013-12-28 21:49:36.936 RetainCycle[1102:303] b retaincount is 2
2013-12-28 21:49:36.937 RetainCycle[1102:303] c retaincount is 1
2013-12-28 21:49:36.937 RetainCycle[1102:303] b retaincount is 1
往下执行:[c release];
[b release];
就会报错