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头文件中,但也可以定义在任何地方。当这个协议只有这个类使用遵守时,一般把协议写在这个类里边,当这个协议需要多个类去实现时,就写在外边单独的文件中。

时间: 2024-07-30 10:19:23

OC中分类、类扩展、Block、协议(由协议引出的代理模式)的相关文章

分类 类扩展 继承 协议 委托

分类 类扩展 继承 协议 委托 分类(Category) 不产生新类,不修改原类,但有自己的.h和.m文件 分类只能向原类中增加方法,或者重写原类的方法 声明的@property只会生成getter setter方法的声明 类.h中定义的方法必须实现,但分类.h中定义的方法,可以不实现 同名方法,分类的优先级高类别主要有3个作用:(1)将类的实现分散到多个不同文件或多个不同框架中.(2)创建对私有方法的前向引用.(类.h中未声明,但存在于.m中的私有方法,通过在分类.h中声明一下,就可以在其他类

Objective-C中的类目,延展,协议

Objective-C中的类目(Category),延展(Extension),协议(Protocol)这些名词看起来挺牛的,瞬间感觉OC好高大上.在其他OOP语言中就没见过这些名词,刚看到这三个名词的时候,有种感觉这是不是学习的坎?这东西难不难?能不能学会?经过本人亲自验证,这三个东西理解起来还是蛮简单的,学过C++或者Java的小伙伴对比理解还是蛮轻松的.类目(Category)就是给已有的类扩充相应的方法,扩充的方法是公有的,类目还可以起到分模块的功能,下面会详细说到. 延展(Extens

Runtime of Objective-C 2-理解oc中的类和对象

1: 类Class:       typedef struct objc_class * Class;     从Class的定义可以看出,它是一个 objc_class 结构类型的指针,objc_class又是什么呢? struct objc_class { struct objc_class* isa; struct objc_class* super_class; //root的为null const char* name; long version; long info; long in

OC category (分类,类目),日期类常用用法

学了这么久OC我们都知道OC中的类分为系统类和自定义的类,当我们在使用系统为我们提供的类时有时往往不能满足我们的需要,例如,字符串NSString类提供了比较字符串的方法compare,为数组排序时系统默认的是升序,当需要为数组按降序排序时,一种途径是需要新建一个类写一个降序的方法,而另一个途径就是系统提供的category(分类,类目),分类(类目,category)的目的为了给没有源代码的类添加方法(只能添加方法,不能添加实例变量),是扩充一个类功能的方式之一,为原有类扩充的方法会成为原类的

Arc 自动内存管理 分类Category 类扩展 Block 代码段 和 Protocol协议的一些简单知识的总结

1. Arc的使用 Arc是自动内存管理: arc的使用原则 1).只要对象没有任何强类型指针引用就会被释放’. 2).只要对象被任何强类型指针指引就不会被释放. 弱指针:__weak 被__weak修饰的指针就被称为弱型指针: 强类型指针 默认的指针都是强类型指针: 被__strong修饰的指针也是强类型指针. 使用Arc时可以重写dealloc方法,但是在重写方法时不能手动调用[super dealloc]: 在Arc中通过@property生成的属性如果是OC的对象那么要用Strong来修

oc中分类 扩展 协议的使用及区别

一.分类 1.适用范围 当你已经封装好了一个类(也可能是系统类.第三方库),不想在改动这个类了,可是随着程序功能的增加需要在类中增加一个方法,这时我们不必修改主类,只需要给你原来的类增加一个分类. 将一个大型的类拆分成不同的分类,在不同分类中实现类别声明的方法,这样可以将一个类的实现写到多个.m文件中,方便管理和协同开发. 分类中的方法可以只声明,不实现,所以在协议不支持可选方法的时候(协议现在已经支持可选方法),通常把分类作为非正式协议使用. 2.语法格式 文件中的语法 @interface

OC中类别、扩展、协议与委托

类别(category)--通过使用类别,我们可以动态地为现有的类添加新方法,而且可以将类定义模块化地分不到多个相关文件中.通常只在类别中定义方法. 类别,接口部分的定义,通常该文件命名为已有"类+类别名.h" @interface 已有类 (类别名) //.......方法实现 @end 例如,考虑为NSNumber增加一个类别,则接口部分代码如下 <p style="margin-top: 0px; margin-bottom: 0px; font-family:

黑马程序员——OC学习小结------arc,block,protocol(协议)

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.ARC的判断准则:只要没有强指针指向对象,就会释放对象 1.ARC特点 1> 不允许调用release.retain.retainCount 2> 允许重写dealloc,但是不允许调用[super dealloc] 3> @property的参数 * strong :成员变量是强指针(适用于OC对象类型) * weak :成员变量是弱指针(适用于OC对象类型) * assign

OC中SEL,类别,继承,协议的使用

1.SEL SEL是selector的缩写,selector在OC中作用是定义一个方法变量,通过该方法变量来调用方法.我们在后面的UI中会经常用selector来调用事件方法.下面我将举两个例子来说明SEL的使用. 直接通过方法名来调用,我们先新建一个Student类,并在其中定义一个名叫Test的对象方法.并定义一个输出语句: -(void)test { NSLog(@"这是SEL的测试方法"); } 我们在Main方法中通过SEL调用就会输出以上结果,如下: SEL s = @se