您的位置:首页 > 移动开发 > Objective-C

Objc 协议以及委托 --个人理解

2014-08-06 18:12 204 查看

引子

为了弄明白委托和协议是什么东西以及怎么使用,我经常是隔三差五的在网上找资料来理解它。每次看完各种博客对于“委托和协议”的讲解,没过几天当我又看到“协议”、“委托“这两个关键词的时候,心里又产生一种陌生以及恐惧的感觉!我不认识他了,我又不认识它了!!

今天我又遇见它了,这一次我得记住它!就算记不住,我也要把我今天对”协议“、”委托”的理解程度给记下来。方便下次再遇到这两个东西的时候,进行回忆以及关联思考!所以,我决定了,文章、博客看了这么多,还不如自己动手写以下代码,实践检验真理,让“真理“更加深刻!

代码下载

协议

因自己是从C++开发过来的,所以对Ios 的协议理解和c++作为关联比较。协议类似c++种的抽象类(带有纯虚方法的类叫做抽象类),它只列出了一些列的方法的声明,而并没有方法的实现。即协议是多个类共享的一个方法列表,在协议中所列出的方法是没有相应的实现,有其他使用协议的人(类)类实现。

1. 用”@protocol“ 关键字来声明,类似用”@interface“来声明一个类!
2. 用“@required” 关键字来声明,关键字下面包含的方法声明是使用该协议的类必须要实现的方法。
3. 用“@optional” 关键字来声明,关键字下面包含的方法声明使用该协议的类可选实现的方法。
4. 协议不是一个类。

协议的声明形式:
@protocol delegateName
@required
- (void) requiredFunc1;
@optional
- (void) optionalFunc2;

@end


例子

设题:李四要买一个苹果,但是他不想自己去买,于是他就委托张三帮他卖一个苹果!
那么,用协议和委托怎么来实现呢?

1.声明一个协议“ByAppleDelegate”
//
//  ByAppleDelegate.h
//  ProtocolDemo
//
//  Created by fenglh on 14-8-6.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>

@protocol ByAppleDelegate <NSObject>
@required
- (void) required_byApple;//

@optional
- (void) optional_byApple; //后面不用到该方法!
@end


2.定义和实现一个“张三”类
//
//  ZhangSan.h
//  ProtocolDemo
//
//  Created by fenglh on 14-8-6.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ByAppleDelegate.h"

@interface ZhangSan : NSObject<ByAppleDelegate>  //ZhangSan 类使用了ByAppleDelegate 这个协议!
@end
//
//  ZhangSan.m
//  ProtocolDemo
//
//  Created by fenglh on 14-8-6.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import "ZhangSan.h"

@implementation ZhangSan

//实现ByAppleDelegate协议中的required_byApple方法
- (void) required_byApple
{
NSLog(@"ZhangSan help LiSi bought an Apple! (via required_byApple)");
}
@end


3.定义和实现一个“李四”类
//
//  LiSi.h
//  ProtocolDemo
//
//  Created by fenglh on 14-8-6.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ByAppleDelegate.h"

@interface LiSi : NSObject
{
id<ByAppleDelegate> delegate; //声明一个委托 注:①
}
- (void) IWantByApple;//声明一个李四自己想买苹果的方法

@property(nonatomic, retain) id<ByAppleDelegate> delegate; //例用特性实现它的set和get的访问方法

@end
//
//  LiSi.m
//  ProtocolDemo
//
//  Created by fenglh on 14-8-6.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import "LiSi.h"
#import "ZhangSan.h"

@implementation LiSi
@synthesize delegate;
- (void) IWantByApple
{
NSLog(@"LiSi want to by an apple via delegate ZhangSan!"); //李四想买一个苹果,但是他不想自己买,于是...
[delegate required_byApple]; //于是他就委托别人(张三)去买 ,注:②
}

@end


4. main函数
//
//  main.m
//  ProtocolDemo
//
//  Created by fenglh on 14-8-6.
//  Copyright (c) 2014年 yons. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "ZhangSan.h"
#import "LiSi.h"

int main(int argc, const char * argv[])
{

@autoreleasepool {

ZhangSan * zhangsan = [[ZhangSan alloc] init];//实例化一个张三
LiSi *lisi = [[LiSi alloc] init]; //实例化一个李四
lisi.delegate = zhangsan; //设置李四的委托人是张三
[lisi IWantByApple];  //李四买苹果

}
return 0;
}


5. 输出结果
2014-08-06 18:26:14.996 ProtocolDemo[874:303] LiSi want to by an apple via delegate ZhangSan!
2014-08-06 18:26:14.997 ProtocolDemo[874:303] ZhangSan help LiSi bought an Apple! (via required_byApple)


委托

在注解① 这里声明一个委托!id<ByAppleDelegate> delegate; 没错delegate这就是一个委托!如果这样看起来很别扭,难以理解的话,你可以从C++的角度来理解,如果把它换成用C++的写法那应该是这样:
@interface LiSi : NSObject
{
id<ByAppleDelegate> delegate; //用Ios的写法
ZhangSan * zhangsan;    //用C++的写法,一个指向张三类的指针!
}

上面的第一句和第二句的写法有什么区别吗?有点:
1)第一句,使用了协议以及委托的结合。
1)第一句,id是一个指向任何对象的指针,所以,在注:②中,你不必关心你的委托人是谁!
2)第二句,这里定义了一个指向ZhangSan类的指针,也相当于是一个委托。这里,你需要明确指定委托的人是张三!然后在注:②中,你还要改成这样:
[zhangsan required_byApple];

所以,委托是一种设计模式,李四想要做的事,他委托张三来完成,这就是委托!
(不明白的,可以自己用第二句的语法来代码实现以下!)

7.小结

1.协议,它只是一个方法列表的集合,他只有方法声明而没有方法的实现,由关键字 "@protocol"来声明一个协议。类似于C++的抽象类!
2.委托,它只是一个设计模式,也就是说是一种思想,无论在C++、objc、java 、C#都存在委托,他们的意义是一样的!
3.委托,如果你学过C++开发的话,你可以把它理解成这样:
Class A{
}
Class B{
A * a; //这就是相当于一个委托!!相当于这个类中指向另外一个对象的指针
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息