iOS -
1. Category
Category是给原有类增加方法的,不能增加属性
分类中的@property只会生成getter.setter的声明,不会生成方法的实现及成员变量。
分类可以访问原有类.h中声明的属性
如果一个分类有一个方法和原类方法名相同,那么用原类调用该方法是,实际调用的是分类的方法。
如果多个分类有和原类相同的方法,那么调用时由编译器决定调用哪个。会调用最后一个参与编译的分类中的方法。
2. Extension
可以为类扩充私有的成员变量和方法
写在.m中
@interface 类名 ()
@end
3. Block
Block是iOS一种特殊的数据类型,用来保存某一段代码,在需要的时候再取出来调用
返回值类型 (^blockName)(形参列表); blockName = ^(形参列表){ 代码}; //保存代码
blockName = ^{}
block(); //调用
typedef int (^sumBlock)(int,int); sumBlock = ^(int num1, int num2){ return num1+ num2;}; sumBlock(2,3);
block可以访问外界变量,也可以定义和外界变量相同的变量名,但是默认情况下不能修改外界变量(a传值)
block访问了外界的变量,block会将该外界变量拷贝一份到堆内存中
int a = 10; void (^block)() = ^{ NSLog("%i", a); //拷贝了一份a=10到堆内存 }; a = 20; block(); //此时打印的是10
block如若要修改外界变量的值,需要在外界变量前加__block.此时如果block修改了外界变量的值,那么会影响到外界变量的值(地址传值&a)
默认情况下,block存储在栈中。如果对block进行copy操作,则block会转移到堆中
如果block在栈中,访问了外界的对象,不会对对象进行retain操作。如果block在堆中,访问外界的对象,会对对象进行retain
如果对象中的block又用到了对象自己,那么应该将对象修饰为__block,避免内存泄露
4. protocal
@protocal 协议名称 <NSObject> 方法声明; @end //-------------------------- @interface 类名: 父类名 <协议1,协议2> @end
协议只能写方法声明,不能声明属性
子类会遵循父类遵循的协议
OC是单继承,一个类只能由一个父类,但能遵循多个协议
一个协议可以遵守其他协议
协议中的方法默认是required的,如果实现协议的类没有实现某个方法,那么会报警告。此时用@optional修饰该方法,则不会报警告
使用场景:类型限制,某个类必须具备某种功能
Wife<WifeCondition> *wife;
if(self.wife responseToSelector:@selector(cooking)){[self.wife cooking];} //如果wife没有实现cooking会报警告
5. 代理模式
当前协议属于谁,就将协议定义到谁的.h文件中
协议的名称以它属于的哪个类的类名开头,后面加上protocal或delegate
协议中的方法名称一般以协议的名称protocal之前的作为开头
一个类中的代理名称叫做delegate
一个类成为另一个类代理时,在.h中用@protocal 协议名称;告诉当前类这是一个协议,在.m中用#import真正道义一个协议的声明