1、@class关键字介绍
(1)概念:只是声明是一个类,但是调用不了这个类里面的方法。
(2)作用:只是定义成员变量、属性。
(3)好处:当import导入的文件里面的方法变动了,引用的地方也要跟着改变,而且还需要重新编译一次,影响程序效率。但是使用@class关键字声明的类就不用跟着改变,效率比较高。
2、@class和import的区别
(1)import方式会导入被引用类的所有信息,包括被引用类的变量和方法,而且运行时也会对其编译,影响效率;@class方式只是告诉编译器,@class修饰的只是类的声明,具体这个类里面有什么信息,不需要知道,等实现文件中真正要用到时,才会真正去查看这个类中的信息。
(2)使用@class方式只需要知道被引用类的名称就可以了。
(3)import方式如果引入的文件中稍有改动,都要重新编译一次,这样造成效率低,使用@class就不会出现这样的问题。
3、Category(分类)
(1)概念:对类进行扩展,只能扩展方法,不能扩展成员变量,不需要创建子类,也不需要知道其源代码,分类实现了类方法模块化,把不同方法分配到不同的分类文件中。
(2)作用:可以为已存在的类添加新的方法,跟继承不一样,可以实现把不同的方法分割到不同的类中去编写,最终加载合并到一起运行。
(3)好处:当你在定义类的时候,突然发生需求变化,但是又不想改变原来的东西,那么可以使用分类进行扩展;使用分类可以进行分工合作,提高代码编写效率。
(4)例子:(在不改变Student类文件的基础上新添一个test2方法)
Student.h文件中:
#import
@interface Student :NSObject
-(void) test
@end
Student.m文件中:
#import “Student.h”
@implementation Student
-(void) test{
NSLog(@”test方法”);
}
@end
//创建一个分类,新添test2方法。
Student+Test.h分类声明文件中
#import “Student.h”
@interface Student (Test) //()代表是一个分类,括号中的名称代表分类名称
-(void) test2
@end
Student+Test.m分类实现文件中
#import “Student+Test.h”
@implementation Student (Test)
-(void) test2{
NSLog(@”扩展了一个test2方法”);
}
@end
4、Protocol :协议介绍
(1)概念:就是一系列方法的列表,其中声明的方法可以被任何类实现。
(2)用法:里面的方法可以只用部分,这点跟java的接口不一样,里面方法可以不全部实现。一个协议可以遵守多个协议,多个协议之间用逗号隔开,相当于拥有了其他协议中的方法声明,只要父类遵守了某个协议,就相当于子类也遵守了。
(3)基协议:NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它。因为NSObject协议中声明很多OC框架中的基本方法 比如description,retain,release等
(4)例子:(监听按钮事件)
Button.h文件:
#import
//<>代表实现某个协议
@protocol ButtonDelegate
-(void) onClick;
@end
@interface Button : NSObject
@property (noatomic, retain) id<ButtonDelegate> delegate;//声明一个监听器,id后面<>表示实现这个协议
-(void) click; //代表点击了按钮
@end
Button.m文件:
import “Button.h”
@implementation Button
-(void) delloc{
[_delegate release];//回收监听器内存
[super dealloc];
}
-(void) click{
[_delegate onClick]; //调用监听器的点击事件,告诉监听器按钮被点击了。
}
@end
ButtonListener.h文件:
#import
#import “Button.h”
@interface ButtonListener:NSObject
@end
ButtonListener.m文件:
#import “ButtonListener.h”
@implementation ButtonListener
-(void) onClick{
NSLog(@”按钮被点击了。”);
}
5、block(代码块)
(1)概念:用来封装一段代码,可以在任何时候执行。标志是^
(2)用法:可以作为函数参数或者函数的返回值,block有形参,有返回值,和传统的函数指针很类似,只是block是内联函数,默认情况下它对局部变量是只读的,即不能在block里面修改成员变量,要想修改成员变量,需要在外部的变量加有两个下划线的block,即__block。如:
#import
int main(int argc, const char * argv[])
{
__block int a = 20;//注意block前面是两个下划线
void (^myblock)() = ^{
NSLog(@"a = %d",a);
a =10; //外部变量有__block声明,所以在block里面可以修改block的值
NSLog(@"a = %d",a);
};
myblock(a);
return 0;
}
(3)定义block变量的写法:
int (^sumBlock)(int,int);
void (^myBlock)();
(4)block实现封装代码的3种写法:
第一种:
^(int a,int b){
return a + b;
};
第二种:
^(){
NSLog(@"a+b");
};
第三种:
^{
NSLog(@"a+b");
};
(5)block完整应用举例:
#import
//利用typedef定义block类型
typedef int (^MyBlock)(int,int);
// 这样就可以利用MyBlock这种类型来定义block变量
//写法一:利用宏定义去写一个block
void test(){
MyBlock block;
block=^(int a, int b){
return a - b;
};
NSLog(@”%i”,block(10,10));//调用block
}
//写法2:跟写法一一样,利用宏定义去定义一个block
void test2(){
MyBlock b3 = ^(int a,int b){
return a - b;
}
NSLog(@”%i”,b3(10,10));//调用block
};
//或者写法3:不用宏定义,直接用block的写法,原始用法
void test3(){
//定义了一个block,这个block返回值是int类型,接收两个int类型的参数
int (^sum) (int,int) = ^(int a,int b){
return a+b;//该return返回的是block的返回值
}
NSLog(@”%i”,sum(10,10));//调用block
}
void main()
{
test();
test1();
test2();
}