首页 > 代码库 > OC中分类、类扩展、Block、协议(由协议引出的代理模式)
OC中分类、类扩展、Block、协议(由协议引出的代理模式)
一: 分类(Category)
1>Category的概念:就是在不改变原来类的基础上,为类增加一些方法
(1,可以为库中定义的类增加方法;2,可以给自己定义的类增加方 法)仅仅是方法哦
好处:一个类可以有多个文件,编译器会将这些文件按一个类除了,便于团队合作。
2> 代码格式:
自定义类中加分类
Person类
#import "Person.h"@interface Person : NSObject- (void)sayHi;@end@implementation Person- (void)sayHi{ NSLog(@"sayHi----------");}@end
Person类的分类方法
#import "Person+study.h"@interface Person (study)- (void)study;@end@implementation Person (study)- (void)study{ NSLog(@"study-------");}@end
类库中增加分类
NSString分类方法
@interface NSString (NSStringWithNum)- (int)numOfString:(NSString *)string;@end@implementation NSString (NSStringWithNum)- (int)numOfString:(NSString *)string{ int num = 0; for (int i = 0; i<string.length; i++) { char ch = [string characterAtIndex:i]; if (ch>‘0‘&&ch<‘9‘) { num++; } } return num;}@end
Main函数
#import <Foundation/Foundation.h>#import "Person.h"#import "Person+study.h"#import "NSString+NSStringWithNum.h"int main(int argc, const char * argv[]){ @autoreleasepool { // Person *p =[[Person alloc] init];// [p sayHi];// [p study]; NSString *string = @"hello123word456"; NSLog(@"%d",[string numOfString:string]); } return 0;}
3> 注意:
(1):Category只能增加方法,不能增加成员变量。
(2):分类可以访问原来类中的成员变量
(3):如果分类和原类中的方法重名,优先调用分类中的方法,(子类和 父类中,优先调用子类)
(4):多了分类中重名方法,优先级由编译顺序决定。(后编译的分类方 法先调用)
二:类扩展 (匿名分类)class extension
1> 类扩展概念:为类增添一些私有的成员属性和方法
写在.m头文件中
2> 格式:在.m文件中
#import "Person.h"@interface Person ()@property (nonatomic, copy) NSString *name;- (void)sayHi;@end@implementation Person- (void)sayHi{ NSLog(@"sayHi-----------");}@end
3> 思考:为什么要增加类扩展,将成员属性和方法定义为私有的,定义成公公多好,方便调用
(1) 私有的成员变量或方法不是不能供外部访问,可以间接访问通过声明 在外部的方法
(2) 定义成私有的是一种封装的思想,开发者会为外部提供一个公共接口,供外部访问,完成这个公共的方法需要一些其他的方法和属性,而这些方法和属性值,调用者不需要关心,开发者只对公共的方法负责,如果调用者通过其他方法调用了内部私有的方法,开发者对此并不关心。
三:Block数据类型
1> 概念:Block是一种数据类型,用来存放代码块,它是一种封装的思想,
用途:可以用来保存一段执行的代码,如多线程中我们要给队列添加任 务,那么执行的任务可以封装到block代码块中作为参数供函数执 行。
2> 用法:
#import <Foundation/Foundation.h>void gotoWork(void(^myBlock)()){ NSLog(@"-----------"); NSLog(@"????????????"); NSLog(@",,,,,,,,,,"); myBlock(); NSLog(@"99999999999"); NSLog(@"2222222222");}typedef int (^sumBlock)(int, int);int main(int argc, const char * argv[]){ // 按道理说我们在ARC中创建对象的代码必须写在释放池中,因为编译器会将代码加到释放池中 @autoreleasepool { // 用法一:无参无返回值// void (^myBlock)() = ^{// NSLog(@"myBlock--------");// };// myBlock(); // 用法二:有参有返回值// int (^sumBlock)(int, int) = ^(int n, int m){// // return n+m;// };// NSLog(@"%d", sumBlock(3,4)); // 用法三:自定义类型Block使用// sumBlock sumblock = ^(int n, int m){// return n+m;// };// NSLog(@"%d", sumblock(3,4)); // 用法四:访问block代码块外的成员变量,修改block代码块外的成员变量// __block int num = 9;// void (^myBlock)() = ^{// num++;// NSLog(@"%d", num); // 错误,可以访问代码块外的成员变量,因为该成员变量对于代码块// // 来说是一个全局变量,内部可以访问,但是不能修改,如果想修改的话// // 可以用(__block)来修饰该成员变量值// };// myBlock(); // 用法五:Block作为函数的参数使用// gotoWork(^{// // NSLog(@"hello");// }); // 注意:我们在以后的学习中,Block数据类型经常要作为参数或者任务封装到Block数据类型中 } return 0;}
3> 注意:Block访问外部变量
1)Block内部可以访问外部变量;
2)默认情况下,Block内部不能修改外部的局部变量
3)给局部变量加上__block关键字,则这个局部变量可以在block内部进行修改。
四:协议(Protocol)
(1)概念
1.Protocol:就一个用途,用来声明一大堆的方法(不能声明成员变量), 不能写实现。
2.只要某个类遵守了这个协议,就拥有了这个协议中的所有方法声明。
3.只要父类遵守了某个协议,那么子类也遵守。
4.Protocol声明的方法可以让任何类去实现,protocol就是协议。
5.OC不能继承多个类(单继承)但是能够遵守多个协议。继承(:),遵守协议(< >)
6.基协议:<NSObject>是基协议,是最根本最基本的协议,其中声明了很多最基本的方法。
7.协议可以遵守协议,一个协议遵守了另一个协议,就可以拥有另一份协议中的方法声明。
8协议方法声明中的关键字
(1)required (默认)要求实现,若没有实现则警告但不报错
(2)Optional 不要求实现
2>用法:
经常用在代理方法中,只要某个类遵守一个协议,就可以作为另一个类的代理为该类做事情
基本用法:
baby头文件
#import <Foundation/Foundation.h>#import "BabyProtocol.h"@class Nurse;@interface Baby : NSObject@property (nonatomic, strong) id<BabyProtocol> delegate;@property (nonatomic, assign) int age;- (void)cry;- (void)hungry;@end
baby类的.m文件
#import "Baby.h"@implementation Baby- (void)cry{ NSLog(@"%d岁的Baby哭了", self.age); [self.delegate noCry:self];}- (void)hungry{ NSLog(@"%d岁的Baby饿了", self.age); [self.delegate feed:self];}@end
Nurse头文件
#import <Foundation/Foundation.h>#import "BabyProtocol.h"@interface Nurse : NSObject <BabyProtocol>@end
Nurse类的.m文件
#import "Nurse.h"@implementation Nurse- (void)noCry:(Baby *)baby{ NSLog(@"护士哄Baby不要哭");}- (void)feed:(Baby *)baby{ NSLog(@"护士喂Baby吃东西");}@end
协议头文件
#import <Foundation/Foundation.h> @class Baby;@protocol BabyProtocol <NSObject>- (void)noCry:(Baby *)baby;- (void)feed:(Baby *)baby;@end
Main函数
#import <Foundation/Foundation.h>#import "Baby.h"#import "Nurse.h"int main(int argc, const char * argv[]){ @autoreleasepool { Baby *baby = [[Baby alloc] init]; Nurse *nurse = [[Nurse alloc] init]; baby.delegate = nurse; baby.age = 3; [baby cry]; [baby hungry]; } return 0;}
3> 注意:
协议本身写在.h头文件中,但也可以定义在任何地方。当这个协议只有这个类使用遵守时,一般把协议写在这个类里边,当这个协议需要多个类去实现时,就写在外边单独的文件中。
OC中分类、类扩展、Block、协议(由协议引出的代理模式)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。