protocal的一个主要的作用就是解耦合,分割代码实现.进行多继承###
java中有interface,objc中有protocal
//可以看到 被代理的主体中必须要有可以找到代理的引用 然后才能调用引用(另一个类)所实现的方法
//说白了也就是内部方法调用而已
@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指令一样,转移执行代码位置而已!但是为了可重用性(程序可以被多次调用)也为了减少耦合,将有些程序代码交给另一个地方去执行...汇编中是call子函数,protocal 执行的也是相似的功能.所以,产生了第三方代理....java中是interface,objc中是protocal...
明白了它产生的作用,这样我们在使用的时候才能更顺风顺水..
protocal在ios 的cocoa 层面运用随处可见,用来将数据和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 的代码...可以看到这里实现了applicationdelegate的协议
这样的话,继承了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后,当程序运行到某个触发点(tigger),比如 didfinishlaunching,会向app的delegate发送消息,而这些需要通过app持有的delegate执行的消息,其实在底层就是代码函数的跳转..所以我们一般还会将调用者传递过去...进行进一步的处理..
何时发送这个消息 一般是由使用者或者系统决定(比如按下按钮 开机等)......
Q:代理和 block 有什么取舍和异同吗?
A:
- 代理一般比较臃肿,声明和实现进行了分开,在运行的时候,由于是别的类进行工作,一遍要传递数据和临时变量...在实现3个及以上的时候可以考虑使用代理
- 而 block 就和回调函数(c)一样,在事件发生时就直接进行调用,方便而且代码少__.不便之处就是一个block只能在一个地方使用,代理可以一对多...只要它们都实现代理即可(通知是多对多)