protocal的一個主要的作用就是解耦合,分割代碼實現(xiàn).進行多繼承###
java中有interface,objc中有protocal
//可以看到 被代理的主體中必須要有可以找到代理的引用 然后才能調用引用(另一個類)所實現(xiàn)的方法
//說白了也就是內部方法調用而已
@protocol Matherdelegate <NSObject>
-(void) showlogmother;
@end
@interface Mother : NSObject
@property (nonatomic,assign)id<Matherdelegate> delegete;
@end
@implementation Mother
@end
@interface Father : NSObject <Matherdelegate>
@end
@implementation Father
-(void)showlogmother{
NSLog(@"delegate mother");
};
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Mother *mother=[[Mother alloc]init];
Father *father =[[Father alloc]init];
mother.delegete=father;
[mother.delegete showlogmother];
}
return 0;
}
歸根結底是底層代碼的轉移,就和匯編中的called指令一樣,轉移執(zhí)行代碼位置而已!但是為了可重用性(程序可以被多次調用)也為了減少耦合,將有些程序代碼交給另一個地方去執(zhí)行...匯編中是call子函數(shù),protocal 執(zhí)行的也是相似的功能.所以,產(chǎn)生了第三方代理....java中是interface,objc中是protocal...
明白了它產(chǎn)生的作用,這樣我們在使用的時候才能更順風順水..
protocal在ios 的cocoa 層面運用隨處可見,用來將數(shù)據(jù)和UI進行分離..比如最簡單的啟動代碼
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@protocol UIApplicationDelegate<NSObject>
@optional
- (void)applicationDidFinishLaunching:(UIApplication *)application;
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(6_0);
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(nullable NSDictionary *)launchOptions NS_AVAILABLE_IOS(3_0);
- (void)applicationDidBecomeActive:(UIApplication *)application;
- (void)applicationWillResignActive:(UIApplication *)application;
這是最開始的 appdelegate 的代碼...可以看到這里實現(xiàn)了applicationdelegate的協(xié)議
這樣的話,繼承了UIresponder的app就有了處理app啟動時候的能力appdelegate....當app啟動之后,比如 didfinishlaunching 這個方法是如何運行的呢?
S_CLASS_AVAILABLE_IOS(2_0) @interface UIApplication : UIResponder
+(UIApplication *)sharedApplication NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.");
@property(nullable, nonatomic,assign) id<UIApplicationDelegate> delegate;
我們先看uiapplication,uiapplication 是uiresponder的子類,而且這里尤其重要的是@property (....) delegate,這個就是這個application的代理,程序開始的時候,在實例化** appdelegate**和application后,當程序運行到某個觸發(fā)點(tigger),比如 didfinishlaunching,會向app的delegate發(fā)送消息,而這些需要通過app持有的delegate執(zhí)行的消息,其實在底層就是代碼函數(shù)的跳轉..所以我們一般還會將調用者傳遞過去...進行進一步的處理..
何時發(fā)送這個消息 一般是由使用者或者系統(tǒng)決定(比如按下按鈕 開機等)......
Q:代理和 block 有什么取舍和異同嗎?
A:
- 代理一般比較臃腫,聲明和實現(xiàn)進行了分開,在運行的時候,由于是別的類進行工作,一遍要傳遞數(shù)據(jù)和臨時變量...在實現(xiàn)3個及以上的時候可以考慮使用代理
- 而 block 就和回調函數(shù)(c)一樣,在事件發(fā)生時就直接進行調用,方便而且代碼少__.不便之處就是一個block只能在一個地方使用,代理可以一對多...只要它們都實現(xiàn)代理即可(通知是多對多)