[Cocoa]_[Plug-in]
来源:互联网 发布:kindle有必要买吗 知乎 编辑:程序博客网 时间:2024/06/06 17:09
Plug-in
Plug-in即插件,一种扩展程序新特性而不需要改变主程序代码的方式。
创建Plug-in结构
创建plug-in的三种方式:
- Plug-ins 实现一个正式协议
- Plug-ins 从一个非正式协议实现一些方法
- Plug-ins 继承一个抽象类或者具体基础类
发布一个正式Plug-ins协议
如果要使用自己声明的插件协议,只需要在头文件种声明协议即可。如下列:
/* MyGreatImageApp Graphics Filter Interface version 0 MyAppBitmapGraphicsFiltering.h*/#import <Cocoa/Cocoa.h>@protocol MyGreatImageAppBitmapGraphicsFiltering// Returns the version of the interface you're implementing.// Return 0 here or future versions may look for features you don't have!- (unsigned)interfaceVersion;// Returns what to display in the Filter menu.- (NSString *)menuItemString;// The main worker bee: filters the bitmap and returns a modified version.- (NSBitmapImageRep *)filteredImageRep:(NSBitmapImageRep *)imageRep;// Returns the window controller for the settings configuration window.- (NSWindowController *)configurationWindowController;@end
发布一个非正式Plug-ins协议
非正式协议比正式协议要复制一点,主要是有些方法是可选的,有些方法是必须,例子如下:
/* MyGreatImageApp Graphics Filter Interface version 0 MyAppBitmapGraphicsFiltering.h*/#import <Cocoa/Cocoa.h>@interface NSObject(MyGreatImageAppBitmapGraphicsFiltering)// REQUIRED// Returns the version of the interface you're implementing.// Return 0 here or future versions may look for features you don't have!- (unsigned)interfaceVersion;// OPTIONAL// Returns what to display in the Filter menu. Defaults to the plug-in// filename without the extension.- (NSString *)menuItemString;// REQUIRED// The main worker bee: filters the bitmap and returns a modified version.- (NSBitmapImageRep *)filteredImageRep:(NSBitmapImageRep *)imageRep;// OPTIONAL// Returns the window controller for the settings configuration window.// If this method is not implemented, no Settings option is provided.- (NSWindowController *)configurationWindowController;@end
发布一个基础类Plug-in接口
如果你想提供一个功能给所有的Plug-in可以发布一个基础类给所有的Plug-in去继承,如下例子:
声明:
#import <Cocoa/Cocoa.h>@interface MyAppEmbeddingView : NSView{@private NSURL *_URL; void *_reserved1; void *_reserved2; void *_reserved3;}- (id)initWithFrame:(NSRect)frameRect URL:(NSURL)URL;- (unsigned)interfaceVersion;- (NSURL *)URL;- (void)setURL:(NSURL *)URL;@end
实现:
#import "MyAppEmbeddingView.h"@implementation MyAppEmbeddingView- (id)initWithFrame:(NSRect)frameRect URL:(NSURL)URL{ self = [self initWithFrame:frameRect]; [self setURL:URL]; return self}- (unsigned)interfaceVersion{ return 0;}- (void)drawRect:(NSRect)rect{ NSEraseRect(rect);}- (NSURL *)URL{ return _URL;}- (void)setURL:(NSURL *)URL{ [URL retain]; [_URL release]; _URL = URL;}@end
加载Plug-in
加载插件的步骤:
- 在标准位置找到插件
- 加载每个插件的可执行代码
- 通过插件接口验证插件
- 实例化插件
验证Plug-in
如果是正式协议插件,需要检查实现该协议的类有没有都实现该协议的方法即可,代码如下:
- (BOOL)plugInClassIsValid:(Class)plugInClass{ if([plugInClass conformsToProtocol:@protocol(MyGreatImageAppBitmapFiltering)]) { if([plugInClass instancesRespondToSelector: @selector(interfaceVersion)] && [plugInClass instancesRespondToSelector: @selector(menuItemString)] && [plugInClass instancesRespondToSelector: @selector(filteredImageRep)] && [plugInClass instancesRespondToSelector: @selector(configurationWindowController]) { return YES; } } return NO;}
对于非正式协议更简单,只需要检查必须的方法即可,不用检查可选方法,代码如下:
- (BOOL)plugInClassIsValid:(Class)plugInClass{ if([plugInClass instancesRespondToSelector: @selector(interfaceVersion)] && [plugInClass instancesRespondToSelector: @selector(filteredImageRep)]) { return YES; } return NO;}
继承基础类的检查只需要判断实现类的父类即可,代码如下:
- (BOOL)plugInClassIsValid:(Class)plugInClass{ if([plugInClass isSubclassOfClass:[MyAppEmbeddingView class]]) { return YES; } return NO;}
加载Plug-in
NSString *ext = @"plugin";NSString *appSupportSubpath = @"Application Support/KillerApp/PlugIns";// ...- (void)loadAllPlugins{ NSMutableArray *instances; NSMutableArray *bundlePaths; NSEnumerator *pathEnum; NSString *currPath; NSBundle *currBundle; Class currPrincipalClass; id currInstance; bundlePaths = [NSMutableArray array]; if(!instances) { instances = [[NSMutableArray alloc] init]; } [bundlePaths addObjectsFromArray:[self allBundles]]; pathEnum = [bundlePaths objectEnumerator]; while(currPath = [pathEnum nextObject]) { currBundle = [NSBundle bundleWithPath:currPath]; if(currBundle) { currPrincipalClass = [currBundle principalClass]; if(currPrincipalClass && [self plugInClassIsValid:currPrincipalClass]) // Validation { currInstance = [[currPrincipalClass alloc] init]; if(currInstance) { [instances addObject:[currInstance autorelease]]; } } } }}- (NSMutableArray *)allBundles{ NSArray *librarySearchPaths; NSEnumerator *searchPathEnum; NSString *currPath; NSMutableArray *bundleSearchPaths = [NSMutableArray array]; NSMutableArray *allBundles = [NSMutableArray array]; librarySearchPaths = NSSearchPathForDirectoriesInDomains( NSLibraryDirectory, NSAllDomainsMask - NSSystemDomainMask, YES); searchPathEnum = [librarySearchPaths objectEnumerator]; while(currPath = [searchPathEnum nextObject]) { [bundleSearchPaths addObject: [currPath stringByAppendingPathComponent:appSupportSubpath]]; } [bundleSearchPaths addObject: [[NSBundle mainBundle] builtInPlugInsPath]]; searchPathEnum = [bundleSearchPaths objectEnumerator]; while(currPath = [searchPathEnum nextObject]) { NSDirectoryEnumerator *bundleEnum; NSString *currBundlePath; bundleEnum = [[NSFileManager defaultManager] enumeratorAtPath:currPath]; if(bundleEnum) { while(currBundlePath = [bundleEnum nextObject]) { if([[currBundlePath pathExtension] isEqualToString:ext]) { [allBundles addObject:[currPath stringByAppendingPathComponent:currBundlePath]]; } } } } return allBundles;}
0 0
- [Cocoa]_[Plug-in]
- plug-in
- plug-in网址
- C# Plug-in resources
- Eclipse plug-in
- plug in, Basic idea
- ZDA plug-in,删无赦!
- datawindow plug-in
- powerbuilder window plug-in
- Nagios plug-in开发
- 瞎扯plug-in
- PI Achive Plug-In
- Plug-in插件技术
- Plug-In 1.1
- 关于jquery plug-in
- java plug in
- 什么是Java Plug-in
- Codeforce # A Plug-in
- Non-terminating decimal expansion; no exact representable decimal result
- JDBC连接ORCALE并把查询结果保存到txt文本中
- 实现网页页面跳转的几种方法(meta标签、js实现、php实现)
- 让IntelliJ IDEA更好用
- Flex+Java+Oracle详细配置说明,Flex访问Oracle数据库
- [Cocoa]_[Plug-in]
- 使用spring loaded classnotfindexcetpion 反序列化
- 端口限速与端口流控
- Opengl教程之 读取obj并绘制在picturecontrol控件内
- 安全密钥传输浅解
- [iOS]版本更新
- mybatis使用PageHelper分页插件原理
- 8-PS学习总结
- php 判断是移动端还是pc端访问web页面