协议protocol和代理delegate的使用

2023-06-15,,

这里的协议是独立的,不再类里面,所以每个类的头文件都要引入#import "MarryProtoco.h"头文件。。

首先新建一个协议 Protocol:MarryProtoco 里面写代理人要执行的方法,或者可选方法

#import <Foundation/Foundation.h>
@protocol MarryProtoco <NSObject>
//代理人中必须要执行的 。
//做饭
- (void)cook;
//洗衣服
- (void)washCloth;
//看孩子
- (void)lookAfterChild;
//代理人中可选执行的
@optional
//交朋友
- (void)makeFriend;
@end


然后在新建一个老大类,老大类就这让代理人执行方法的类--这里新建的是Boy类

Boy.h文件代码

#import <Foundation/Foundation.h>
#import "MarryProtoco.h"   //Boy引入协议
@interface Boy : NSObject
{
    NSString *_name;
//    id<MarryProtoco> _delegate;
}
@property (nonatomic , copy)NSString *name;
@property (nonatomic , assign)id<MarryProtoco> delegate;//这里因为是id类型的,所以assign,并且这里只能上面id<MarryProtoco> _delegate;同时存在一者,否则会报错。
- (instancetype)initWithName:(NSString *)name;   //代理人是在老大里面设置的
//- (void)setDelegate:(id<MarryProtoco>)delegate;
- (void)work;
- (void)eat;
- (void)play;
@end

Boy.m文件代码

#import "Boy.h"
@implementation Boy
@synthesize name = _name;
- (instancetype)initWithName:(NSString *)name  // 这里这样写是不对的,因为在.h中name是copy类型,如果这样写话是assign类型的写法。应该改成注释后的写法
{
    self = [super init];
    if (self) {
        //_name = name;
        [self setName:name];    //这个才是copy类型变量的写法。。。。可懂?
    }
    return self;
}
- (void)setDelegate:(id<MarryProtoco>)delegate
{
    _delegate = delegate;
}
- (void)work
{
    NSLog(@"%@我要去工作了,早点在家做饭,", _name);
    [_delegate cook];
}
- (void)eat
{
    NSLog(@"%@,我要出去吃饭了,你在家给我好好看孩子", _name);
    [_delegate lookAfterChild];
}
- (void)play
{
    NSLog(@"%@,我要出去玩耍,这些衣服脏了,怎么办?",_name);
    [_delegate washCloth];
}
@end

创建代理类Girl,来执行协议中的方法

Gril.h文件代码

#import <Foundation/Foundation.h>
#import "MarryProtoco.h"   //Gril引入协议
@interface Girl : NSObject<MarryProtoco>
{
    NSString *_name;
   
}
@property (nonatomic , copy)NSString *name;
- (instancetype)initWithName:(NSString *)name;
//代理人必须执行协议里面的全部方法即MarryProtoco里面的方法
//代理人中@optional里面的方法是可选的,可以执行也可以不执行。
- (void)cook;
- (void)lookAfterChild;
- (void)washCloth;
@end

Gril.m文件代码

#import "Girl.h"
@implementation Girl
@synthesize name = _name;
- (instancetype)initWithName:(NSString *)name
{
    self = [super init];
    if (self) {
        //_name = name;
        [self setName:name];
    }
    return self;
}
- (void)cook
{
    NSLog(@"%@我去给您做饭,你别急,马上好", _name);
}
- (void)lookAfterChild
{
    NSLog(@"%@说,好睇,我去看孩子,你去玩吧,玩得开心哦。", _name);
}
- (void)washCloth
{
    NSLog(@"%@说,恩恩,您衣服脏了,我去给你洗洗,嘻嘻,",_name);
}
@end

main.m主函数中的代码写法

#import <Foundation/Foundation.h>
#import "Girl.h"
#import "Boy.h"
#import "MarryProtoco.h"
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        /*
         凡事符合系统默认setter、getter书写格式的方法,都可以使用点语法
         例如:[person setName:@“zhangsan”];
         可以等价写成 person.name = @“zhangsan”;
         
         NSString *name = [person name];
         可以等价写成NSString *name = person.name;
         属性是一对getter、setterfangfa,点语法是属性的另一种调用格式       
         */
        
//        Girl *mm = [[Girl alloc] initWithName:@"妹妹"];
        Girl *mm = [[Girl alloc] init];
        mm.name = @"妹妹";
//        Boy *gg = [[Boy alloc] initWithName:@"哥哥"];
        
        Boy *gg = [[Boy alloc] init];
        gg.name = @"哥哥";
        [gg setDelegate:mm]; //设置代理人,
        [gg work];
        [gg play];
        [gg eat];
        
        //每次只能存在一个代理人,如果想换代理人,就必须让现有的死了,然后在设置代理人
    }
    return 0;
}


《协议protocol和代理delegate的使用.doc》

下载本文的Word格式文档,以方便收藏与打印。