一):block学习总结

block :用来保存一段代码。

1、block 特点:
  1> Block封装了一段代码,可以在任何时候执行 
  2> Block可以作为函数或者函数的返回值,而其本身又可以带输入参数或返回值
  3> 苹果官方建议尽量多用block,在多线程、异步任务、集合遍历、集合排序、动画转场用的很多
  4> Block可以在程序运行时凭空产生一个代码保存起来

 2、block的标志:^

 3、block跟函数很像

1> 可以保存代码
  2> 有返回值
  3> 有形参
  4> 调用方式一样
 4、定义block变量(没有形参)
  1> myblock是变量名,后面的()代表没有形参
   void (^myblock)() = ^(){
   NSLog(@"-----------");
   NSLog(@"-----------");
   };
  2> 没有形参可以省略后面的小括号
  void (^myblock)() = ^{
      NSLog(@"-----------");
      NSLog(@"-----------");
  };

3> 利用block变量调用block内部的代码
  myblock();
 
5、定义指向函数的指针int(*p)(int, int); 能用指向函数的指针做的东西一般用block替代

6、定义block变量(有形参)

1> 返回值是int,接收两个int类型的参数
  int (^sumblock)(int,int) = ^( int n1, int n2 ){
      return n1+n2;
  };
  2> 调用
  int a =  sumblock(3,4);
  3> 输出
  NSLog(@"%d", a);

7、使用typedef定义指向函数的指针类型

typedef int (*SumP)(int,int);

8、使用typedef定义block类型

1> typedef int (^MyBlock)(int,int);
  2> 用block计算两个值的和
  MyBlock sumBlock = ^(int  a, int b){
      return a + b;
   };

小结

block要掌握的东西

 1、如何定义block变量

int (^sumBlock)(int,int);
 void(^myBlock);
 
 2、如何利用block封装代码

1> 有形参
 ^(int a, int b) {
    return a-b;
 }
  2> 没有形参
 ^() {
    NSLog(@"----");
 }
 
 ^() {
 NSLog(@"----");
 }
 
 3、block访问外面变量
  1> block内部可以访问外面的变量
  2> 默认情况下,block内部不能修改外面的局部变量
  3> 给局部变量加上__block,这个局部变量就可以在block内部修改
 
 4、利用typedef定义block类型
 
 typedef int (^MyBlock)(int, int);   以后就可以利用MYBlock这种类型来定义block变量
 
  1> 先定义变量再进行赋值
MyBlock b1,b2;

b1 = ^(int a, int b){
    return a+b;
};

2> 定义变量同时赋值
MyBlock b3 = ^(int a, int b){
    return a+b;
};

二) protocol学习总结

 1、定义了一个叫MyProtocol的协议

1> @protocol仅仅是用来声明方法的,声明完方法后等着类来实现
  2> 只要类遵守了这个协议就意味着这个类拥有了这个协议的所有方法声明
  3> 对这个方法可以加个关键字来约束这个方法要不要实现,@required代表必须实现,不实现就会发送警告,默认的就是这个@optional可以不实现
  4> NSObject,它是一个基协议,最根本最基本的协议
    protocol MyProtocol
    @required  必须实现
    - (void)test;
    @optional  可以不实现
    - (void)test2;
    @end

 2、协议的遵守

1> 只有一个类遵守了某一个协议,就拥有了这份协议中的所有方法声明
   2> : 继承父类
   3> <> 遵守协议
   4> 可以遵守多个协议,在<>里面协议之前用逗号隔开
  @interface Person : NSObject
  @end
   5> 要求obj3保存对象必须遵守Myprotocol
   NSObject *obj3 = [[NSObject alloc] init];
   6> 代表利用set方法设置这个对象的时候,这个对象必须遵守这个协议
  @property (nonatomic, strong) id obj;

 3、协议遵守协议

一个协议遵守了另外一个协议,就可以拥有这份协议的所有方法声明
  @protocol MyProtocol3

4、协议的规范

1> 告诉编译器这两个家伙是个协议,可以取代import
   2> 这样在.m文件里就要包含协议的.h头文件
   3> 遵守原则,先写协议,真正要用的时候再写头文件,提高性能
  @protocol MyProtocol2;
  @protocol MyProtocol3;

总结

1、协议的定义
 @protocol 协议名称
 // 方法声明列表
 @end
 
 2、如何遵守协议
  1> 类遵守协议
 @interface 类名 :父类名 <协议名称1,协议名称2>
 @end
 
  2> 协议遵守协议
 @protocol 协议名称 <其他协议名称1,其他协议名称2>
 @end
 
 3、.协议中方法声明的关键字
  1> @required(默认)
 要求实现,如果没有实现会发生警告
  2> @optional
 不要求实现,怎样都不会有警告
 
 4、定义一个变量的时候,限制这个变量保存的对象遵守某个协议
  1> 类名<协议名称> *变量名;
  2> id<协议名称> 变量名;
  3> NSObject *obj;
  4> id obj;
 如果没有遵守对应的协议,编译器会警告
 
 5、@property中声明的属性也可以用做一个遵守协议的限制
  1> @property (nonatomic, strong) 类名<协议名称> *属性名
  2> @property (nonatomic, strong) id<协议名称> 属性名
  3> @property (nonatomic, strong) Dog *dog;
  4> @property (nonatomic, strong) id dog;
 
 6、协议可以定义在单独.h文件中,也可以定义在某个类中
  1>如果这个协议只用在某个类中,应该把协议定义在该类中
  2>如果这个协议用在很多类中,就应该定义在单独文件中
 
 7、分类可以定义在单独.h文件中,也可以定义在原来类中
  1> 一般情况下,都是定义在单独文件中
  2> 定义在原来类中的类,只要求能看懂语法

8、基协议
  1> NSObject是个基类,最根本最基本的类,任何类最终都要继承他
  2> 其实还有个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议
  3> NSObject协议中声明很多最基本的方法,比如description,retatin、release
  4> 建议每个协议都要遵守基协议

protocol的代理

1> 仅仅告诉编译器Button是一个类
@class Button;
2> 定义一个协议,并且遵守基协议
@protocol ButtonDelegate
3> 监听器的思想,当某个按钮被点击了会告示他哪个按钮被点击了
- (void)onClick:(Button *)but;
@end
4> 使Button 这个类遵守协议
@interface Button : NSObject
- (void)click;
5> 声明中的属性遵守这个协议
@property (nonatomic, retain) id delegate;
@end
@implementation Button
6> 防止unrecognized selector sent to instance 0x100114f10,方法未实现或没有这个方法,判断有没有实现这个方法
- (void)click
{
    如果_delegate实现onClick:方法,就调用这个方法
    if ([_delegate respondsToSelector:@selector(onClick:)])
    {
         按钮被点击了就应该通知监听器,并且告诉监听器哪个按钮被点击了
        [_delegate onClick:self];
    }
    else
    {
        NSLog(@"监听器没有实现onClick:方法");
    }
}
@end

block作为代理回调
#import
1> 仅仅告诉编译器Button是个类
@class Button;
2> 用typedef定义block类型,没有返回值
typedef void (^MyButton)(Button *);

@interface Button : NSObject
3> 定义一个自动生成MyButton类型的setter和getter,生成_btn这个成员变量
@property (nonatomic, assign) MyButton btn;
- (void)click;
@end

@implementation Button
4> 方法实现,用_btn变量调用block内部的代码
- (void)click
{
    调用block
     _btn(self);
}
@end

int main()
{
    @autoreleasepool {
        Button *b = [[[Button alloc] init] autorelease];

调用setter方法
       b.btn = ^(Button *btn){
       
            NSLog(@"点了这个-%@按钮", btn);
       };
       
 调用方法
       [b click];
 
    }
    return 0;
}

补充:判断stu有没有遵守这个协议
 Student *stu = [[[Student alloc] init] autorelease];
       
        if ([stu conformsToProtocol:@protocol(Study)])
        {
            NSLog(@"%@遵守了这个协议",stu);
        }

黑马程序员_ Objective-c 之block、protocol学习笔记的更多相关文章

  1. 大数据-将MP3保存到数据库并读取出来《黑马程序员_超全面的JavaWeb视频教程vedio》day17

    黑马程序员_超全面的JavaWeb视频教程vedio\黑马程序员_超全面的JavaWeb教程-源码笔记\JavaWeb视频教程_day17-资料源码\day17_code\day17_1\ 大数据 目 ...

  2. 2016年8月17日 内省(1)18_黑马程序员_使用beanUtils操纵javabean

    8.内省(1):18_黑马程序员_使用beanUtils操纵javabean 1.导入两个包: 2.调用静态方法. 9.泛型 map.entrySet() :取出map集合的键值对组成一个set集合. ...

  3. 黑马程序员_高新技术之javaBean,注解,类加载器

    ----------- android培训.java培训.java学习型技术博客.期待与您交流! ---------- 第一部分 javaBean 一,由内省引出javaBean 1,内省: 内省对应 ...

  4. 黑马程序员_ JAVA中的多线程

    ------- android培训.java培训.期待与您交流! ---------- 尽管线程对象的常用方法可以通过API文档来了解,但是有很多方法仅仅从API说明是无法详细了解的. 本来打算用一节 ...

  5. JavaWeb开发之四:servlet技术 黑马程序员_轻松掌握JavaWeb开发之四Servlet开发 方立勋老师视频教程相当的经典

    总结: 记住:servlet对象在应用程序运行的过程中只创建一次,浏览器每次访问的时候,创建reponse对象 request对象,然后调用servlet的service方法,reponse对象和re ...

  6. 黑马程序员_ Objective-c 面向对象笔记详解

    1)类,对象,方法 类 类名: 1) 类名的第一个字母必须是大写 2) 不能有下划线 3) 多个英文单词,用驼峰标识 类的声明和实现 类的声明 @interface 类名 : NSObject { @ ...

  7. 黑马程序员_ Objective-c 概述及面向对象与三大特性

    -----------android培训.java培训.java学习型技术博客.期待与您交流!------------ (一).语法概述 1. oc介绍:(.m文件) 1> c语言的基础上,增加 ...

  8. 黑马程序员_ Objective-c 之Foundation笔记(二)

    NSArray NSArray的创建 NSArray *array = [NSArray arrayWithObject:@“jack”]   创建单个元素 NSArray *array3 = [NS ...

  9. 黑马程序员_ Objective-c 内存管理笔记

    引用计数器 当一个对象被创建出来,就要分配给内存这个对象,当不用这个对象的时候,就要及时的回收,为了可以明确知道对象有没有被使用,就要用引用计数器来体现,只要计数器不为0,表明对象被使用中. 1.方法 ...

随机推荐

  1. [c++] stack的使用

         cout <<        ; i<; i++)          first.push(i);      cout <<                   ...

  2. 微软雅黑 在css里怎么写

    1.首先要了解css中是如何控制字体的. font:在一个声明中设置所有字体属性: font有以下几个属性: font-style:字体样式 font-variant:字体异体 font-weight ...

  3. mysql 与 mycat集成读写分离

    1,先说下同步数据库原理,其实很简单.就是在主库做数据库操作的时候,会生成一个本地日志,日志会在my.ini当中配置看图一,读库会实时去扫描日志,如果有更新就直接在读库执行. 这个是主库my.ini配 ...

  4. MIT JOS学习笔记02:kernel 01(2016.10.28)

    未经许可谢绝以任何形式对本文内容进行转载! 在文章开头不得不说的是,因为这部分的代码需要仔细理清的东西太多,所以导致这篇分析显得很啰嗦,还请谅解. 我们在上一篇文章已经分析了Boot Loader的功 ...

  5. oracle单机改变归档路径

    oracle 归档日志文件路径设置 1.  查看LOG_ARCHIVE_DEST 与 ( LOG_ARCHIVE_DEST_n 或 DB_RECOVERY_FILE_DEST )参数情况注意(  LO ...

  6. JAVA之Forward 和 Redirect的区别

    1.从地址栏显示来说forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址 ...

  7. Java-适配器

    对于Java程序来说,如果一个类要实现一个接口,则必须要覆写此接口中的全部抽象方法,那么如果此时一个接口中定义了抽象方法过多,但是在子类中有用不到这么多的抽象方法,则肯定很麻烦,所以此时需要一个中间的 ...

  8. IDEA创建maven项目使用命令打包遇到的问题及解决方法

    maven项目命令打包springboot项目 首先打开tomcat命令工具(如图所示):

  9. Centos6.5 设置Tomcat8 service服务实现自启动和服务管理

    Centos6.5 设置Tomcat8 service服务实现自启动和服务管理 将tomcat设置成像apache,nginx一样. 用serviec xxxx start/stop/restart ...

  10. FileSystem.DeleteDirectory遇到"无法删除 文件:无法读取源文件或磁盘"

    Microsoft.VisualBasic.FileIO.FileSystem.DeleteDirectory(fileFolder, UIOption.AllDialogs, RecycleOpti ...