ios笔记--class关键字,Category,protocol和block笔记

来源:互联网 发布:有限元分析软件下载 编辑:程序博客网 时间:2024/06/07 06:45


1、@class关键字介绍

(1)概念:只是声明是一个类,但是调用不了这个类里面的方法。

(2)作用:只是定义成员变量、属性。

(3)好处:当import导入的文件里面的方法变动了,引用的地方也要跟着改变,而且还需要重新编译一次,影响程序效率。但是使用@class关键字声明的类就不用跟着改变,效率比较高。

 

2@classimport的区别

(1)import方式会导入被引用类的所有信息,包括被引用类的变量和方法,而且运行时也会对其编译,影响效率;@class方式只是告诉编译器,@class修饰的只是类的声明,具体这个类里面有什么信息,不需要知道,等实现文件中真正要用到时,才会真正去查看这个类中的信息。

(2)使用@class方式只需要知道被引用类的名称就可以了。

(3)import方式如果引入的文件中稍有改动,都要重新编译一次,这样造成效率低,使用@class就不会出现这样的问题。

 

3、Category(分类)

(1)概念:对类进行扩展,只能扩展方法,不能扩展成员变量,不需要创建子类,也不需要知道其源代码分类实现了类方法模块化,把不同方法分配到不同的分类文件中

(2)作用:可以为已存在的类添加新的方法,跟继承不一样,可以实现把不同的方法分割到不同的类中去编写,最终加载合并到一起运行。

(3)好处:当你在定义类的时候,突然发生需求变化,但是又不想改变原来的东西,那么可以使用分类进行扩展;使用分类可以进行分工合作,提高代码编写效率。

4)例子:(在不改变Student类文件的基础上新添一个test2方法)

Student.h文件中:

#import<Foundation/Foundation.h>

@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

 

4Protocol :协议介绍

(1)概念:就是一系列方法的列表,其中声明的方法可以被任何类实现。

(2)用法:里面的方法可以只用部分,这点跟java的接口不一样,里面方法可以不全部实现。一个协议可以遵守多个协议,多个协议之间用逗号隔开,相当于拥有了其他协议中的方法声明,只要父类遵守了某个协议,就相当于子类也遵守了。

(3)基协议:NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它。因为NSObject协议中声明很多OC框架中的基本方法 比如descriptionretainrelease

4)例子:(监听按钮事件)

Button.h文件:

#import<Foundation/Foundation.h>

//<>代表实现某个协议

@protocol  ButtonDelegate<NSObject> //定义了一个叫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<Foundation/Foundation.h>

#import “Button.h”

@interface ButtonListener:NSObject<ButtonDelegate>

@end

 

ButtonListener.m文件:

#import “ButtonListener.h”

@implementation ButtonListener

-(void) onClick{ 

NSLog(@”按钮被点击了。”);

}

 

5、block(代码块)

1)概念:用来封装一段代码,可以在任何时候执行。标志是^

2)用法:可以作为函数参数或者函数的返回值,block有形参,有返回值,和传统的函数指针很类似,只是block是内联函数,默认情况下它对局部变量是只读的,即不能在block里面修改成员变量,要想修改成员变量,需要在外部的变量加有两个下划线的block,__block。如:

#import <Foundation/Foundation.h>

 

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)();

4block实现封装代码的3种写法:

第一种:

^(int a,int b){

    return a + b;

 };

 第二种:

 ^(){

    NSLog(@"a+b");

 };

 第三种:

 ^{

    NSLog(@"a+b");

 };

5block完整应用举例:

#import<Foundation/Foundation.h>

//利用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();

}

0 0