码迷,mamicode.com
首页 > 其他好文 > 详细

黑马程序员-OC加强学习日记-分类、协议、block类型

时间:2015-12-18 09:06:40      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

 

 ------- ios培训、 android培训、java培训、期待与您交流! ----------

 

一.分类  Gategroy

1.创建一个分类   

@interface  类名 (分类名)

@end

@implementation 类名 (分类名)

@end

  技术分享      

2.特点:(1)扩展已有类的功能

           (2)分类中可以访问原有类的成员变量(定义在头文件中的成员变量)

3.语法步骤:(1)创建一个分类

                 (2)在分类中增加新方法的声明和实现

4.注意点:(1)分类不可以为原有类增加定义成员变量, @property在分类中只生成gettersetter方法的声明,不能生成实现和成员变量

              (2)分类可以扩充系统自带的类功能,给NSObject增加分类会影响所有的类

5.分类方法定义规范:不能定义与原有类同名方法,分类之间也不要有同名方法。

   如果同名,分类中的方法会覆盖原有类方法(哪怕没有导入这个分类的头文件)

   多个分类有同名方法,最后编译的那个会覆盖其他

 

代码演示:

  计算字符串中有多少个数字(0~9

 1 #import <Foundation/Foundation.h>
 2 
 3 // 为NSString类增加一个找数字的方法
 4 
 5 @interface  NSString (tool)
 6 
 7 - (int) countOfNum;
 8 
 9 @end
10 
11 @implementation NSString (tool)
12 
13 - (int) countOfNum
14 
15 {  // 定义计数器
16 
17      int counter =0;
18 
19 // 遍历字符串
20 
21      for(int i=0;i<self.length;i++){
22 
23          unichar c = [str characterAtIndex:i];
24 
25          if(c>=0&&c<=9){
26 
27          counter ++;
28 
29           }
30 
31        }
32 
33    return counter;
34 
35 }
36 
37 @end
38 
39 int main(int argc ,const char * argv[]){
40 
41       @autoreleasepool{
42 
43          NSString * str = @"123itcast456heima789";
44 
45          int rs = [str countOfNum];
46 
47          NSLog(@"%d",rs);
48 
49        }
50 
51    return 0;
52 
53 }

 

二.类扩展  Extension

  在.m文件中,为类增加私有属性和方法

@interface  类名 ()  // 括号里没有内容

     int _age;// 增加私有成员变量

}

@property (nonatomic,copy) NSString *name;// 增加私有属性

-(void) show;// 增加私有方法

@end

 

@implementation 类名 ()

-(void) show

{

    NSLog(@"私有属性和方法只能在本类中使用")

}

@end

 

三.SEL

 SEL 是一种数据类型,代表方法签名。通过签名可以找到对象上的方法

1.格式: SEL  变量名称  (定义变量)

        通过@selector(方法名称)  快速生成一个SEL

        SEL类型变量可以作为方法参数和返回值

2.重点掌握:表示某个对象能否响应一个方法

  BOOL isUse = [对象 respondsToSelector:@selector(方法名)]

 

四.block

1.概念:block是一种数据类型,作用是封装代码。

       函数不能在方法内部或函数内部定义,block可以

2.定义block类型变量的格式

  返回值类型  (^变量名称) (形参列表) =  ^返回值类型  (形参列表)  {语句};  

 

(1)定义一个无参无返回值block类型变量

       void (^test)() = ^{

            NSLog(@"test");   

            };

(2)定义一个有参无返回值block类型变量

   void(^test)(NSString *name) = ^(NSString *name){

         NSLog(@"%@",name);

       };

(3)定义一个有参有返回值类型变量

       int (^sum) (int num1,int num2) = ^int (int num1,int num2){

             return num1 + num2;

           };

 3.作为函数、方法参数类型的格式

          返回值类型 (^)  (形参列表)

 

 代码演示:

 1 #import <Foundation/Foundation.h>
 2 
 3 //定义一个CZPerson类
 4 
 5 @interface CZPerson : NSObject
 6 
 7  // 声明一个求平均值的类方法
 8 
 9 + (int) average:(int(^)(int num1,int num2))sum;
10 
11 @end
12 
13 @implementation CZPerson
14 
15 + (int) average:(int(^)(int num1,int num2))sum
16 
17 {
18 
19       return sum(10,20)/2;
20 
21 }
22 
23 @end
24 
25 int main(int argc ,const char * argv[]){
26 
27       @autoreleasepool{
28 
29           int rs =[CZPerson average:^int (int num1,int num2){
30 
31              return num1 + num2; 
32 
33            }];
34 
35          NSLog(@"%d",rs);
36 
37       }
38 
39    return 0;
40 
41 }

 

4.block使用场景

多个方法中很多代码是相同的,只有一部分代码经常变化。可以把经常变化的代码通过block参数传入

5.注意点:

1block中可以访问局部变量。默认在block内部不能修改局部变量的值,如果想修改局部变量的值,在定义这个变量的时候,前面加上__block。但是这个时候,外边的局部变量和block内部这个不是同一个变量,只是值保持了同步

2block内部使用对象的时候,block内部对这个对象有一个强引用。 直到block作用域结束,对象才被释放。在block作用域给对象赋值nil也无济于事 

3)可以利用typedefblock类型起别名

      typedef 返回值类型 (^block类型名称)(参数列表)

但是这种方法不好用。常规格式可读性比较好

 

五.协议   protocol

协议:对象之间的约定,只有方法声明没有方法实现。类似于接口 

1.定义格式:

  @protocol  协议名称 <NSObject> // 默认遵守NSObject协议

     方法声明

     ……

  @end

快速创建协议文件

    技术分享技术分享

 

2.遵守协议:要先把要遵守的协议头文件拷贝过来

 (1)类遵守协议

      @interface  类名 :父类 <协议名称列表>

      @end

 (2)协议遵守协议

      @protocol  协议名称 <其他协议名称列表>

      @end

3.注意点:(1)协议不能声明成员变量,不能写实现

              (2)只要某个类遵守了某个协议,就拥有这个协议里所有的方法声明

              (3)父类遵守了某个协议,子类也遵守

              (4)类能遵守多个协议,但是不能继承多个类  (继承:  遵守<>)

              (5)协议可以遵守协议,一个协议遵守了另一个协议,就拥有另一个协议的所有方法声明

              (6)通过id<协议名称定义出来的指针,能指向任意实现这个协议的实例对象 

                     通过这个方法可以实现多态

4.两个关键字

 (1@required (默认)

      从@required开始到@optional之间所有的方法声明必须实现,否则编译器警告

 (2@optional

      @optional以下的方法声明可以选择实现

 

代码演示

 //定义一个Play协议

1 #import <Foundation/Foundation.h>
2 
3 @protocol  Play  <NSObject>
4 
5  // 声明PlayGame方法
6 
7 -(void) playGame;
8 
9 @end

 

//定义一个CZIphone类,遵守<Play>协议

 1 #import <Foundation/Foundation.h>
 2 #import "Play.h"
 3 
 4 @interface CZIphone :NSObject <Play>
 5 
 6 -(void) playGame;
 7 
 8 @end
 9 
10 @implementation CZIphone
11 
12 -(void) playGame
13 
14 {
15 
16        NSLog(@"%S",__func__);
17 
18 }
19 
20 @end

 

//定义一个CZIpad类,遵守<Play>协议

 1 #import <Foundation/Foundation.h>
 2 #import "Play.h"
 3 
 4 @interface CZIpad :NSObject <Play>
 5 
 6 -(void) playGame;
 7 
 8 @end
 9 
10 @implementation CZIpad
11 
12 -(void) playGame
13 
14 {
15 
16       NSLog(@"%S",__func__);
17 
18 }
19 
20 @end

 

//定义一个CZBeauty

 1 #import <Foundation/Foundation.h>
 2 #import "CZIpad.h"
 3 #import "CZIphone.h"
 4 #import "Play.h"
 5 
 6 @interface CZBeauty :NSObject <Play>
 7 
 8 // 通过id <play> 定义一个成员变量
 9 
10 @property (nonatomic,strong) id <Play> player;
11 
12 -(void) wantPlayGame;
13 
14 @end
15 
16 @implementation CZBeauty
17 
18 -(void) wantPlayGame
19 
20 {
21 
22       [self.player playGame];
23 
24 }
25 
26 @end

 

// 测试主程序

 1 #import <Foundation/Foundation.h>
 2 #import <CZBeauty.h>
 3 #import "CZIpad.h"
 4 #import "CZIphone.h"
 5 #import "Play.h"
 6 
 7 int main(int argc ,const char * argv[]){
 8 
 9    @autoreleasepool{
10 
11          CZBeauty * beauty = [[CZBeauty alloc] init];
12 
13          CZIpad * ipad = [[CZIpad alloc] init];
14 
15          CZIphone * iphone = [[CZIphone alloc] init];
16 
17          beauty.player = ipad;
18 
19         [beauty wantPlayGame]; // iPad玩游戏
20 
21          beauty.player = iphone;
22 
23         [beauty wantPlayGame]; // iphone玩游戏
24 
25    return 0;
26 
27 }

 

5.prototcl类型限制 

    格式: id <协议名称对象名 = [[类名 alloc] init];

   类要遵守这个协议,创建出来的实例对象才能符合某些条件

 

代码演示:

  一个美女想找个男朋友

  1.必须富   2.高 帅者优先

 定义一个协议 

 1 #import <Foundation/Foundation.h>
 2 
 3 @protocol boy  <NSObject>
 4 
 5 -(void) fu;//
 6 
 7 @optional
 8 
 9 -(void) gao;//
10 
11 -(void) shuai;//
12 
13 @end

 

//定义一个CZBoyfriend

 1 #import <Foundation/Foundation.h>
 2 #import "boy.h"
 3 
 4 @interface CZBoyfriend :NSObject <boy>
 5 
 6 -(void) fu;
 7 
 8 -(void) gao;
 9 
10 @end
11 
12 @implementation CZBoyfriend
13 
14 -(void) fu
15 
16 {
17 
18       NSLog(@"%s",__func__);
19 
20 }
21 
22 -(void) gao
23 
24 {
25 
26      NSLog(@"%s",__func__);
27 
28 }
29 
30 @end

 

////定义一个CZBeauty

 1 #import <Foundation/Foundation.h>
 2 #import "CZBoyfriend.h"
 3 #import "boy.h"
 4 
 5 @interface CZBeauty :NSObject
 6 
 7 // 定义一个遵守<boy>的成员变量
 8 @property (nonatomic,strong) CZBoyfriend <boy> * bf
 9 
10 @end
11 
12 @implementation CZBeauty
13 
14 @end

 

//测试主程序

 1 #import <Foundation/Foundation.h>
 2 #import "CZBoyfriend.h"
 3 #import "boy.h"
 4 #import "CZBeauty.h"
 5 
 6 int main(int argc ,const char * argv[]){
 7 
 8        CZBeauty * beauty = [[CZBeauty alloc] init];
 9 
10        CZBoyfriend * boyf = [[CZBoyfriend alloc] init];
11 
12        beauty.bf = boyf;// 此美女现在有了一个富高的男朋友
13 
14   return 0;
15 
16 }

 

6.protocol 代理模式

 (1)概念:传入的对象,代替当前类完成了某些功能 例如保姆与Baby

 (2)思路定义一个协议,声明代理类需要实现的方法

               创建一个代理类(保姆),遵守上面的协议

              在需要代理的类(Baby)中,定义一个对象类型为id且遵守代理协议的成员变量

              在Baby类调用成员变量的方法,调用保姆的方法

              在使用Baby类的文件中,为代理类赋值

 (3)使用场景:对象A发生一些行为,告知对象B

                      对象B监听对象A的一些行为

                      对象A无法处理某些行为,让对象B帮忙处理

 

           

 

  

 

 

 

      

 

 

 

 

 

黑马程序员-OC加强学习日记-分类、协议、block类型

标签:

原文地址:http://www.cnblogs.com/ly0709/p/5056019.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!