黑马程序员— block、protocol和Foundation

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

  上一章我们学习了OC内存管理的相关知识,了解了OC程序在运行中对象及变量是如何释放以达到不占用内存的效果。本章我们来学习OC的block,protocol协议和Foundation框架。

第一讲     block

1. block简介

  block封装了一段代码,可以在任何时候执行

  block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值。

  苹果官方建议尽量多用block。在多线程、异步任务、集合遍历、集合排序、动画转场用的很多

2. block的定义

  block的标志:^,block是用来保存一段代码

  block跟函数很像:

  1.可以保存代码

  2.有返回值

  3.有形参

  4.调用方式一样

1> 如何定义block变量

int (^sumBlock)(int, int);  // 带参数

void (^myBlock)();          // 不带参数

2> 如何利用block封装代码

^(int a, int b) {     // 带参数a和b

   return a - b;

};

^() {         // 不带参数

  NSLog(@"----------");

};

^ {       // 不带参数并且省略小括号()

  NSLog(@"----------");

};

3.  block访问外面变量

  * block内部可以访问外面的变量

  * 默认情况下,block内部不能修改外面的局部变量

  * 给局部变量加上__block关键字,这个局部变量就可以在block内部修改

4. 利用typedef定义block类型

typedef int (^MyBlock)(int, int);

// 以后就可以利用MyBlock这种类型来定义block变量

MyBlock block;

MyBlock b1, b2;

b1 = ^(int a, int b) {

return a - b;

};

MyBlock b3 = ^(int a, int b) {

return a - b;

};

下面我们通过代码来学习一下block跟局部变量之间的关系:

 1 void test()
 2 {
 3     int a = 10;
 4     __block int b = 20;
 5
 6     void (^block)();
 7
 8     block = ^{
 9         // block内部可以访问外面的变量
10         //NSLog(@"a = %d", a);
11
12         // 默认情况下,block内部不能修改外面的局部变量
13         // a = 20;
14
15         // 给局部变量加上__block关键字,这个局部变量就可以在block内部修改
16         b = 25;
17     };
18     block();
19 }

第二讲     protocol协议

一、 protocol协议

1. 协议的基本用途

  *可以用来声明一大堆方法(不能声明成员变量)

  *只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明

  *只要父类遵守了某个协议,就相当于子类也遵守了

2. 协议的定义

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

  // 方法声明列表....

@end

3. 如何遵守协议

  1> 类遵守协议

*只要某个类遵守了协议,就拥有了这个协议中得所有方法声明,父类遵守,子类完全遵守。

@interface 类名 : 父类名 <协议名称1, 协议名称2>

@end

  2> 协议遵守协议

*一个协议可以遵守其他多个协议,多个协议之间用逗号 , 隔开

*一个协议遵守了其他协议,就相当于拥有了其他协议中的方法声明

@protocol 协议名称 <其他协议名称1, 其他协议名称2>

@end

4. 协议中方法声明的关键字

协议中有2个关键字可以控制方法是否要实现(默认是@required),在大多数情况下,用途在于程序员之间的交流

  1> @required (默认)

  要求实现,如果没有实现,会发出警告

  2> @optional

  不要求实现,怎样不会有警告

5. 定义一个变量的时候,限制这个变量保存的对象遵守某个协议

类名<协议名称> *变量名;

id<协议名称> 变量名;

NSObject<MyProtocol> *obj;

id<MyProtocol> obj2;

如果没有遵守对应的协议,编译器会警告

6. @property中声明的属性也可用做一个遵守协议的限制

@property (nonatomic, strong) 类名<协议名称> *属性名;

@property (nonatomic, strong) id<协议名称> 属性名;

@property (nonatomic, strong) Dog<MyProtocol> *dog;

@property (nonatomic, strong) id<MyProtocol> dog2;

7. 协议可用定义在单独.h文件中,也可用定义在某个类中

1> 如果这个协议只用在某个类中,应该把协议定义在该类中

2> 如果这个协议用在很多类中,就应该定义在单独文件中

8. 分类可用定义在单独.h和.m文件中,也可用定义在原来类中

1> 一般情况下,都是定义在单独文件

2> 定义在原来类中的分类,只要求能看懂语法

9. 基协议

  *NSObject是一个基类,最根本最基本的类,任何其他类最终都要继承它

  *其实还有一个协议,名字也叫NSObject,它是一个基协议,最根本最基本的协议

  *NSObject协议中声明很多最基本的方法,比如description、retain、release等

  *建议每个新的协议都要遵守NSObject协议

二、 代理设计模式

1. 设计原理

  有些麻烦的事情不想自己亲自做,就可以找个人帮忙做,即交给代理对象去做

2. 设计原则

  *首先得拥有某个代理对象属性

  *其次要很清楚代理有哪些方法

  *最后要保证能解耦

3. 实现方案

  *定义一个protocol,在其中声明一些和代理沟通的方法

  *拥有一个代理属性id<protocol> delegate

  *让代理遵守protocol

第三讲     Foundation框架

Foundation框架中包含了很多开发常用的数据类型,结构体、枚举等。下面列举出常用的结构体。

一、 Foundation框架-结构体

1. NSRange(location length)表示范围

创建变量的三种方式

  NSRange r1 = {1,2}; // 可读性差

  NSRange r2 = {.location = 1,length = 2}; // 代码冗长

  NSRange r3 = NSMakeRange(1,2); // Foundation自带函数,常用

查找字符串的范围

  NSString *str = @”jack andy”;

  NSRange r = [str rangeOfString:@”rose”];

// 找不到,location=NSNotFound=-1;length=0.

2. NSPoint/CGPoint表示坐标

NSPoint p1 = CGPointMake(1,2)//常用

CGPoint p2 = NSMakePoint(1,2)

3. NSSize/CGSize表示UI元素的的尺寸(宽度,高度)

NSSize s1 = CGSizeMake(100, 50);

NSSize s2 = NSMakeSize(100, 50);

CGSize s3 = NSMakeSize(200, 60);

4. NSRect/CGrect(CGPoint CGsize)UI元素的位置和尺寸

CGRect r1 = CGRectMake(0, 0, 100, 50);

CGRect r2 = { {0, 0}, {100, 90}};

CGRect r3 = {p1, s2};

CGPointZero == CGPointMake(0,0);//原点

// 利用框架中函数将结构体转为字符串

NSString *str = NSStringFromPoint(p1);

二、 Foundation框架-字符串

1. NSString:不可变字符串

(1)创建字符串的六种形式

  *NSString *s1 = @"jack";

  *NSString *s2 = [[NSString alloc] initWithString:@"jack"];

  *NSString *s3 = [[NSString alloc] initWithFormat:@"age is %d", 10];

// C字符串 --> OC字符串

  *NSString *s4 = [[NSString alloc] initWithUTF8String:"jack"];

// OC字符串 --> C字符串

  *const char *cs = [s4 UTF8String];

  *NSUTF8StringEncoding 用到中文就可以用这种编码

NSString *s5 =[[NSString alloc] initWithComtentsOfFile:@”文件路径” encoding:NSUTF8StringEncoding error:nil];

// URL : 资源路径

// 协议头:// 路径

// file://

// ftp://

NSURL *url = [[NSURL alloc] initWithString:@”file://文件路径”]

NSURL *url = [NSURL fileURLWithPath:@”文件路径”];

NSString *s6 = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];

[NSURL URLWithString:(NSString *)]; // 一般都会有个类方法跟对象方法配对,类方法通常以类名开头

(2)字符串的导入导出

// 字符串的导出

  [@”haha” writeToFile:@”文件路径” atomically:YES NSUTF8StringEncoding error:nil];

  NSString *str = @”haha123”;

  NSURL *url = [NSURL fileURLWithPath:@”文件路径”];

  [str writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];

2. NSMutableString:可变字符串

  NSMutableString *s1 = [NSMutableString stringWithFormat:@"Hello my Kitty "];

// 拼接内容到s1的后面

  [s1 appendString:@" ohoh"];

// 获取my的范围

// 一个获取范围,一个进行删除

  NSRange range = [s1 rangeOfString:@"my"];

  [s1 deleteCharactersInRange:range];//删除my之后的字符串

// 不可变字符串实现拼接成新的字符串

  NSString *s2 = [NSString stringWithFormat:@"Hello Kitty"];

// s2的内容拷贝一份,加上字符串返回新的字符串

  NSString *s3 = [s2 stringByAppendingString:@" oh my god"];

三、 Foundation框架-集合

1. NSArray和NSMutableArray

  1>NSArray是OC中使用的数组,只能存放OC对象,不能存放非OC对象类型,如int、struct、enum等等

创建OC数组:

  NSArray *array1 = [NSArray arrayWithObject:@”jack”];//单个元素

// 多个元素,结尾必须以nil结尾

  NSArray *array2 = [NSArray arrayWithObjects:@”jack”,@”andy”,nil];

// 快速创建一个OC数组

  NSArray *array3 = @[@”jack”,@”andy”];

// 访问OC数组元素和C语言一样

  array2[0] ;

// 获取数组元素的个数

  array.count;

  2>NSArray的遍历

 1 #import "Person.h"
 2
 3 int main()
 4 {
 5       Person *p = [[Person alloc] init];
 6
 7       NSArray *array = @[p, @"jack", @"andy"];
 8
 9       // for循环快速遍历数组元素
10      // id obj代表着数组中的每一个元素
11       for (id obj in array)
12       {
13          // 快速找出obj元素在数组中的位置
14          NSUInteger i = [array indexOfObject:obj];
15
16          NSLog(@"%ld - %@", i, obj);
17       }
18       // 使用block遍历
19       // 每遍历一个元素,就会调用一次block,并把当前元素的索引位置当作参数传给block
20      [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
21           NSLog(@"%ld - %@", idx, obj);
22
23          if (idx == 0)
24          {
25                // 停止遍历
26                *stop = YES;
27          }
28      }];
29       return 0;
30 }

  3>NSMutableArray

  NSMutableArray *array = [NSMutableArray arrayWithObjects:@"haha", @"andy", nil];

// 添加元素

  [array addObject:@"Kitty"];

// 删除元素

  [array removeAllObjects];

// 删除指定的对象

  [array removeObject:@"haha"];

// 删除指定索引的元素

  [array removeObjectAtIndex:1];

// 错误写法

  [array addObject:nil];

// @[]只能创建不可变数组NSArray

  NSMutableArray *array = @[@”andy”];// 错

2. NSSet和NSMutableSet

  1>NSSet

  NSSet *s = [NSSet set];

// 创建多元素NSSet

  NSSet *s1 =[NSSet setWithObjects:@”jack”,@”andy”,nil];

// 随机取出一个元素

  NSString *s2 = [s1 anyObject];

  2>NSMutableSet

  NSMutableSet *s = [NSMutableSet set];

// 添加元素

  [s addObject:@”haha”];

// 删除指定元素

  [s removeObject:(id)];

  3>NSSet和NSArray

都是集合,都能存放多个对象

都只能存放OC对象

本身不可变,都有一个可变的子类

不同:NSSet无序,NSArray有序

3. NSDictionary和NSM

  根据key找到value。里面存储的东西都是键值对。

  1>NSDictionaryutableDictionary

// 创建字典

  NSDictionary *dict = [NSDictionary dictionaryWithObject:@”jack” forKey:@”name”];

// 快速创建字典

  NSDictionary *dict = @{@”name”:@”jack”};

// 访问

// 根据key获取对应的值

  id obj = [dict objectForKey:@”name”];

// 快速访问

  id obj = dict [@”name”];

// 添加、移除键值对

  [dict setObject:@”jack” forKey:@”name”];

  [dict removeObjectForKey:(id)];

  2>遍历

NSDictionary的遍历和上面提到的NSArray的遍历是一样的,可以通过for循环和block遍历,下面我只写一下block遍历。

  [dict enumerateKeysAndObjectsUsingBlock:

    ^(id key, id obj, BOOL *stop) {

    NSLog(@"%@ - %@", key, obj);

// *stop = YES;

  }];

  注意:字典不允许有相同的key,但允许有相同的value,字典也是无序的。

  3>NSMutableDictionary

创建、访问等和父类一样,唯一要注意的地方是下面这个:

//返回的是NSDictionary类型的

  NSMutableDictionary *dict = @{@"name" : @"jack"};

  [dict setObject:@"rose" forKey:@"name"];

四、 NSNumber、NSDate、NSValue

1. NSNumber

将基本数据类型包装成对象

  NSNumber *num = [NSNumber numberWithInt:25];

  NSDictionary *dict [email protected]{@”age”: num};

  NSNumber *num1 = dict[@”age”];

  int a = [num2 intValue];

编译器特性:自动将基本数据类型包装成对象

NSArray *aray = @{@”age”:@20};

@’A’ ;//NSNumber对象 @(age)

@”A”;//NSString对象

2. NSValue

NSNumber继承自NSValue。

// 结构体--->OC对象

CGPoint p = CGPointMake(10, 10);

// 将结构体转为Value对象

NSValue *value = [NSValue valueWithPoint:p];

// 将value转为对应的结构体

// [value pointValue];

NSArray *array = @[value ];

3. NSDate

// 创建一个时间对象

NSDate *date = [NSDate date];

// 打印出的时候是0时区的时间(北京-东8区)

NSLog(@"%@", date);

NSDate *date2 = [NSDate dateWithTimeInterval:5 sinceDate:date];

// 从1970开始走过的秒数

NSTimeInterval seconds = [date2 timeIntervalSince1970];

// [date2 timeIntervalSinceNow];

//日期格式化

  NSString *time = @"2015/4/10 23:11";

  NSDateFormatter *formatter = [[NSDateFormatter alloc] init];

//y年M月d日 24时m分

  formatter.dateFormat = @"yyyy/MM/dd HH:mm";

  NSDate *date = [formatter dateFromString:time];

本章学习总结:

  本章的主要学习了block,protocol协议和Foundation框架,其中重点是Foundation框架,其实一开始学习OC时就用#import用过Foundation框架,但没有深入学习,本章的第三讲主要就学习Foundation框架,感觉虽然提供了很多很好用的对象和方法,但是偏概念和记忆性的东西比较多,虽然通过视频的学习都能理解Foundation的知识内容,但是整个回顾起来就有点晕了,因为确实有点多。这就需要我们平时多加练习,慢慢领会,因为Foundation是我们今后开发中非常重要的框架,必须我们熟练的掌握。

  本章主要分为三讲内容,第一讲主要学习了block,要掌握定义block变量,和利用block封装代码,熟练掌握block的基本定义规范以及使用。第二讲我们主要学习了protocol协议,要掌握协议的定义和如何遵守协议,协议方法声明的两个关键字要知道怎么使用。第三讲主要学习了Foundation框架,也是本章最重要的内容,总结了结构体、字符串、集合等不同的Foundation框架的使用,可能知识有点多,但需要多巩固练习,争取熟记下这些框架的内容。

时间: 2024-12-12 20:53:49

黑马程序员— block、protocol和Foundation的相关文章

黑马程序员——有关protocol的小结

在OC程序中经常会有这样的问题就是一个类想让其他类帮自己实现某些方法,然后再将结果返回给这个类:如何让一个类要找的代理去实现自己想要的方法呢? 这样就需要有一个协议,让能遵守协议的其他类都能实现协议中的方法声明,成为该类的代理. protocol的使用原则: 1.可以用来声明很多方法,但是不能声明成员变量. 2.只要一个类遵守了这个协议,就相当于拥有了这个协议中所有的方法声明,然后在自己的.m文件中实现就行了. 3.只要父类遵守了这个协议,就相当于子类也遵守了这个协议. protocol的使用方

黑马程序员 block,protocol

#import <Foundation/Foundation.h> // 利用typedef创建block typedef int (^MyBlock) (int,int); // <>表示遵守协议 @protocol MyProtocol <NSObejct> /* 1.reqiured:要求实现方法,不实现方法编译器会发出警告 2.optional:不要求实现方法 3.默认情况下为reqiured 4.协议之间可以相互遵守,一个协议可以遵守多个协议<....,

黑马程序员-block代码块和protocol协议

一.block block是一个变量,这个变量类似c语言中的函数指针,在回调场合用的特别多.它可以封装代码,有返回值有形参.下面通过代码来说明block的定义和使用. 首先来看没有返回值没有形参的block 1 void (^myblock)() = ^{ 2 NSLog(@""); 4 }; 有返回值有形参的block 1 int (^sumblock)(int, int) = ^(int a, int b){ 2 return a + b; 3 }; 4 5 int c = sum

黑马程序员----block

1.block的基本使用 block用来保存一段代码: block的标志: ^: block跟函数很像: 可以保存代码: 有返回值: 有形参: 调用方式一样: 2.没有返回值.没有形参的block 先定义一个block变量:如:myBlock: 利用block变量调用block里面的代码: 3.有返回值和形参的block 先定义一个block变量:如:sumBlock: 利用block变量调用block里面的代码: 4.利用typedef定义block类型 先定义Myblock类型: 利用定义过

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

NSArray NSArray的创建 NSArray *array = [NSArray arrayWithObject:@“jack”]   创建单个元素 NSArray *array3 = [NSArray arrayWithObjects:@"jack", @"rose", nil] 创建多个元素 快速创建一个NSArray对象 NSArray *array4 = @[@"jack", @"rose", @"4

黑马程序员_ Objective-c 之Foundation之NSNumber ,NSValue, NSDate

Objective-c 之Foundation之NSNumber ,NSValue, NSDate 1.NSNumber具体用法如下: 在Objective-c中有int的数据类型,那为什么还要使用数字对象NSNumber.这是因为很多类(如NSArray)都要求使用对象,而int不是对象.NSNumber就是数字对象,我们可以使用NSNumber对象来创建和初始化不同类型的数字对象. 此外,还可以使用实例方法为先前分配的NSNumber对象设定指定的值,这些都是以initWith开头,比如in

黑马程序员_ Objective-c 之Foundation笔记(一)

结构体  NSRange: 用来表示范围 创建 NSRange r1 = {2, 4} NSRange r2 = {.location = 2, .length = 4} NSRange r3 = NSMakeRange(2, 4) 查找某个字符串在str中的范围 NSString *str = @"i love oc"; NSRange range = [str rangeOfString:@"java"] NSLog(@"location = %ld,

黑马程序员——OC学习小结------Foundation框架

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.常用的结构体 NSRange (location,length) NSPoint\CGPoint (x,y) NSSize\CGSize (width, height) NSRect\CGRect (CGPoint,CGSize) NSRange void range() { /* @"i love oc" love的范围 NSRange r1 = {2, 4}; // 不用 N

黑马程序员_OC学习笔记之Foundation框架集合类

OC--集合类 1.OC集合类包括NSArray,NSSet,NSDictionary都是以面向对象的方式操作数组,而且OC数组不像C语言中的数组只能存放同一种数据类型,它可以存放任意类型的对象,但是不能存放非OC对象类型如基本数据类型int,struct,enum等 2.OC数组是以对象的方式存在,因此在创建的时候需要为创建的对象前面加* 3.NSArray数组一旦创建就决定了是不是可变,而且永远是可变或不可变 4.NSArray数组和子类NSMutableArray的基本操作: 1>使用NS