何為協議,何為委托,何為分類(類別)?
委托 即 代理 delegate:
他是 (接口的實現類)類似c中的回調。
把某個對象要做的事情委托給別的對象去做。 那么別的對象就是這個對象的代理,來代替他處理要做的事情。
在code中,首先你要明確一個對象的委托方是誰,委托的內容是什么。
在mfc中,每個程序都要繼承自cwinapp,就是要重寫幾個虛函數額。
但是在cocoa中,我們來實現個UIApplicationDelegate代理,不用繼承,我們只需要考慮你要捕獲的應用程序生命周期中的函數就可以了。
可以這樣用指針來看: 類a中有一個類b的指針,那么b就是a的代理委托。a干完一件事情就需要告訴b,b調用對應的方法來做出相應的響應。
ios開發中: 如:視圖之間傳輸信息。 兩個頁面uiview 來實現傳值,用delegate可以很好地做到。
來看一個demo:
- @interface A: UIView
- @property(nonatic, retain) id aValueDelegate;
- @end;
- @implementation A
- - (void) fa
- {
- NSString *value = @"hello";
- [aValueDelegate aValue:value];
- }
- @end;
- @interface B: UIView
- NSString *value;
- @end;
- @implementation B
- - (void) aValue:(NSString *)fromValue
- {
- value = fromValue;
- NSLog(@"%@", value);
- }
- @end;
- A *a = [[A alloc] init];
- B *b = [[B alloc] init];
- a.aValueDelegate = b; //設置a代理委托對象為b
類別:category
主要3個功能
1、利用類別分散實現。
2、利用類別創建前向引用,實現私有函數
3、非正式協議和委托類別
- @interface NSString(NumberConvenience)
- -(NSNumber*) lengthAsNumber;
- @end
協議:
類似於c++的純虛函數(java中的接口), 只有聲明,沒有實現, 你需要在子類中實現。
其中@optional 屬性方法不要求必須實現。
@required屬性 要求實現協議的類必須要實現方法。
如果不確定協議是否被實現,可以使用respondsToSelector:@select()來判斷。
協議不是類,就是簡單定義了一個其他對象可以實現的接口。
demo是采用源哥博客(http://blog.csdn.net/xie376450483/article/details/7646617)的代碼:
代碼根據xcode的升級,有些許改動。
非正式協議: 是使用類別category來實現,他是nsobject的一個類別。這樣任何類的對象都可以作為委托對象來使用。他可以列出對象能夠執行的多種方法。這樣用來實現委托我們可以使用選擇器來判斷非正式協議中是否有這個方法。
- @interface NSObject (***Delegate)
- //method
- @end
- //
- // Dog.h
- // protocol2
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- @interface Dog : NSObject
- @property int ID;
- @end
- @interface NSObject(myCategory)
- - (void)callFromNSObject;
- @end
- //
- // Dog.m
- // protocol2
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import "Dog.h"
- @implementation Dog
- - (id)init
- {
- self = [super init];
- return self;
- }
- @end
- @implementation NSObject(myCategory)
- - (void)callFromNSObject
- {
- NSLog(@"iam nsobject");
- }
- @end
- //
- // Person.h
- // protocol2
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import "Dog.h"
- @interface Person : NSObject
- //{
- // Dog *dog;
- //}
- @property Dog *dog;
- - (void)callFun;
- @end
- //
- // Person.m
- // protocol2
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import "Person.h"
- @implementation Person
- @synthesize dog;
- - (void) callFun
- {
- NSLog(@"Call Fun!");
- [dog callFromNSObject];
- }
- @end
- //
- // main.m
- // protocol2
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import "Dog.h"
- #import "Person.h"
- int main(int argc, const charchar * argv[])
- {
- @autoreleasepool {
- Dog *dog = [[Dog alloc]init];
- [dog setID:10];
- Person *qy = [[Person alloc]init];
- [qy setDog:dog];
- [qy callFun];
- }
- return 0;
- }
正式協議:
一個命名方法列表。 與非正式的區別在於:他要求顯示采用協議,采用協議的方法是在類的@interface聲明中列出協議的名稱。 這時實現協議的類應該遵守協議,承諾實現協議中的所有方法。
- @protocol NSCopying
- -(id) copyWithZone:(NSZone *) zone;
- @end
- @interface Car : NSObject<NSCopying>
- {
- // instance variable
- }
- // method
- @end // Car
cocoa china中的總結:
1.協議聲明了可以被任何類實現的方法
2.協議不是類,它是定義了一個其他對象可以實現的接口
3.如果在某個類中實現了 協議 中的某個方法,也就是這個類實現了那個 協議 。
4.協議經常用來實現委托對象。一個委托對象是一種用來協同或者代表其他對象的特殊對象。
5:委托,就是調用自己定義方法,別的類來實現。
6.新特性說明
@optional預編譯指令:表示可以選擇實現的方法
@required預編譯指令:表示必須強制實現的方法
2.協議不是類,它是定義了一個其他對象可以實現的接口
3.如果在某個類中實現了 協議 中的某個方法,也就是這個類實現了那個 協議 。
4.協議經常用來實現委托對象。一個委托對象是一種用來協同或者代表其他對象的特殊對象。
5:委托,就是調用自己定義方法,別的類來實現。
6.新特性說明
@optional預編譯指令:表示可以選擇實現的方法
@required預編譯指令:表示必須強制實現的方法
- @protocol myprotocol <NSObject>
- @optional
- -(void)print:(int)value;
- //可選的方法
- @required
- -(int)printValue:(int)value1 andValue:(int)value2;
- //必須實現的
- @end
- #import <Foundation/Foundation.h>
- #import "myprotocol.h"
- //實現協議 myprotocol
- @interface mytest : NSObject<myprotocol>
- - (void)showInfo;
- @end
- #import "mytest.h"
- @implementation mytest
- -(void)showInfo
- {
- NSLog(@"I am in showInfo");
- }
- //實現協議必須實現的
- -(int)printValue:(int)value1 andValue:(int)value2
- {
- NSLog(@"print value1 %d,value2 %d",value1,value2);
- return 0;
- }
- //實現可選的
- -(void)print:(int)value
- {
- NSLog(@"print value is %d",value);
- }
- @end
- #import <Foundation/Foundation.h>
- #import "mytest.h"
- #import "myprotocol.h"
- int main (int argc, const charchar * argv[]) {
- @autoreleasepool {
- mytest *test=[[mytest alloc]init];
- [test showInfo];
- [test printValue:20 andValue:30];
- //print協議是可選的,所以在用之前一定要判斷是否實現了,不然可能會出錯,使用下面的方法
- // [test print:20];
- SEL sel=@selector(print:);
- if([test respondsToSelector:sel]){
- [test print:11];
- }
- //用協議的方式實現
- id<myprotocol> protocol =[[[mytest alloc]init]autorelease];
- [protocol showInfo];
- [protocol printValue:200 andValue:300];
- if([protocol respondsToSelector:@selector(print:)]){
- [protocol print:111];
- }
- }
- return 0;
- }
最后看一個demo,加深理解:
- //
- // Dog.h
- // catagory
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- @protocol dogBark;
- @interface Dog : NSObject
- {
- int barkCount;
- NSTimer *timer;
- }
- @property int ID;
- @property (assign)id<dogBark> delegate; //dog master
- @end
- @protocol dogBark <NSObject>
- - (void)bark: (Dog*)thisDog count:(int)count;
- @end
- //
- // Dog.m
- // catagory
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import "Dog.h"
- @implementation Dog
- //ID use _ID
- @synthesize delegate;
- - (id)init
- {
- if (self = [super init]) {
- //create nstimer user, 1.0s use updateTimer:nil
- timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(updateTimer:) userInfo:nil repeats:YES];
- }
- return self;
- }
- - (void) updateTimer:(id)arg
- {
- barkCount++;
- NSLog(@"dog bar %d", barkCount);
- //user master delegate bark:count
- [delegate bark:self count:barkCount];
- }
- @end
- //
- // person.h
- // catagory
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import "Dog.h"
- @interface person : NSObject<dogBark>
- {
- Dog *_dog;
- }
- @property (retain, nonatomic) Dog *dog;
- @end
- //
- // person.m
- // catagory
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import "person.h"
- @implementation person
- - (void)setDog:(Dog *)aDog
- {
- if (_dog != aDog) {
- [_dog setDelegate:self];
- }
- }
- //dog use person interface
- - (void)bark:(Dog *)thisDog count:(int)count
- {
- NSLog(@"person bark: this dog %d bark %d", [thisDog ID], count);
- }
- @end
- //
- // main.m
- // catagory
- //
- // Created by peter on 14-2-25.
- // Copyright (c) 2014年 peter. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import "Dog.h"
- #import "person.h"
- int main(int argc, const charchar * argv[])
- {
- @autoreleasepool {
- person *qy = [[person alloc]init];
- Dog *dog = [[Dog alloc]init];
- [dog setID:10];
- [qy setDog:dog];
- while (1) {
- [[NSRunLoop currentRunLoop]run];
- }
- }
- return 0;
- }
解釋一下循環:
[[
NSRunLoop
currentRunLoop
]
run
]; run是一種cocoa構造,一直處於阻塞狀態, 知道某些事情發生未知。
run循環等待用戶事件的時候,將一直保持運行而不會返回。