青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

羅朝輝(飄飄白云)

關(guān)注嵌入式操作系統(tǒng),移動平臺,圖形開發(fā)。-->加微博 ^_^

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  85 隨筆 :: 0 文章 :: 169 評論 :: 0 Trackbacks
深入淺出 Cocoa 之 Plugin
CC許可,轉(zhuǎn)載請注明出處

在前文 深入淺出 Cocoa 之 Framework 中講解了 Framework,接下來講解 plugin。如果你對 Framework 還不太熟悉的話,請閱讀那篇文中,在本例中使用到了 framework,并在本文中沒有詳細(xì)講述其創(chuàng)建和使用過程。

本文代碼下載:點(diǎn)擊這里

為什么要引入插件?
我們知道編譯程序時,會連接相關(guān) framework,通常我們所連接的框架是 Foundation 和 Application 框架。當(dāng)程序啟動運(yùn)行時,每個被連接到的 framework 都會被加載到該程序的 objc 運(yùn)行時環(huán)境中。如果我們想向正在運(yùn)行的程序加載新的 framework,那該怎么辦呢?答案之一就是使用 plugin 機(jī)制。cocoa 的 plugin 機(jī)制通常由 NSBundle 類來實(shí)現(xiàn),而實(shí)現(xiàn)動態(tài)加載的功能由函數(shù) objc_addClass 來完成。一般我們無需與 objc_addClass 這個函數(shù)打交道,我們使用 NSBundle 來完成絕大部分與 plugin 相關(guān)的工作。

plugin 機(jī)制能夠讓我們開發(fā)出高度模塊化,可定制以及可擴(kuò)展的應(yīng)用程序,并能夠讓第三方為該應(yīng)用程序添加新特性。想必很多人都熟悉 Eclipse,Eclipse 的 plugin 機(jī)制就非常方便與強(qiáng)大。

NSBundle 簡介
束(bundle)是文件系統(tǒng)中的一個目錄結(jié)構(gòu),它將程序會使用到的資源打包在一起。這些資源可包括編譯好的代碼,nib文件,配置文件,圖像,聲音,本地化資源等等。束是 Mac OS X 的一個核心特性,應(yīng)用程序,F(xiàn)ramework,插件都是一個束,只是擴(kuò)展名各異,如應(yīng)用程序的擴(kuò)展名為 .app;Framework 的擴(kuò)展名是 .framework;插件的擴(kuò)展名默認(rèn)為 .bundle。

一個 plugin 就是一個 bundle(束),xcode 默認(rèn)以 .bundle 為擴(kuò)展名。通常我們使用我們自己定義的擴(kuò)展名,以便與系統(tǒng)或其他人編寫的 plugin 區(qū)分開來。我們通過 NSBundle 來載入 bundle,并把其中經(jīng)過編譯的類注冊到 objc 運(yùn)行時中,然后我們就能在程序中使用這些類了;我們也可以使用 bundle 中的所有資源。

plugin 構(gòu)架
我們可以通過多種途徑來實(shí)現(xiàn)一個 plugin:
1,定義一個 objc protocol,讓 plugin 遵守該 protocol;
2,定義一個基類,讓 plugin 繼承該基類;
3,定義一個 C 回調(diào)函數(shù)接口,讓 plugin 實(shí)現(xiàn)改回調(diào)函數(shù);
4,使用 CFPlugIn 來創(chuàng)建 plugin 接口;
在今天的例子中,使用的是第二種情況,這種情況稍稍復(fù)雜一些,我們需創(chuàng)建一個 framework 供宿主程序(使用插件的程序)和 plugin 使用,該 framework 的主要職責(zé)是提供基類接口。

plugin 的存放目錄
通常 plugin 總是存放在以下三個位置:
1,應(yīng)用程序名.app/Contents/Plug-ins   這是程序的開發(fā)者存放隨產(chǎn)品發(fā)布的插件的地方。 
2,~/Library/Application Support/應(yīng)用程序名/Plug-ins  用戶存放個人插件的地方。
3,/Library/Application Support/應(yīng)用程序名/Plug-ins   系統(tǒng)中供全部用戶使用的插件。
 
在今天的例子中,使用的是第一種情況,即將插件存放在應(yīng)用程序包中。

創(chuàng)建宿主程序
我們來創(chuàng)建一個名為 PluginDemo 的 cocoa application,該程序含有一個顯示已安裝 plugin 的 popup button 以及一個執(zhí)行選中 plugin 的 button。


創(chuàng)建 framework
1,創(chuàng)建名為 PluginFramework 的 framework,向其中添加 plugin 基類:AbstractPlugin。如果你忘記怎樣創(chuàng)建和使用 framework,請參看前文:深入淺出 Cocoa 之 Framework


AbstractPlugin 類僅僅提供兩個接口:name 用來標(biāo)識 plugin,run 用來供宿主程序運(yùn)行插件。
- (NSString *)name;
- (IBAction)run:(id)sender;

2,在 PluginDemo 中連接和使用該 framework 來運(yùn)行插件。如果你忘記怎樣連接和使用 framework,請參看前文:深入淺出 Cocoa 之 Framework。我們在按鈕響應(yīng)函數(shù)中,運(yùn)行選中的插件。
- (IBAction)runPlugin:(id)sender
{
    AbstractPlugin 
*plugin = [[pluginsController selectedObjects] lastObject];
    
if (!plugin)
        
return;

    [plugin run:sender];
}

創(chuàng)建 plugin
1,創(chuàng)建 plugin;


2,連接 PluginFramework;如果你忘記怎樣連接和使用 framework,請參看前文:深入淺出 Cocoa 之 Framework

3,創(chuàng)建 UI 界面;


4,創(chuàng)建繼承自基類的 plugin 子類:PluginOne;

PluginOne 類繼承自 AbstractPlugin,它僅僅是顯示和隱藏一個 window,其實(shí)現(xiàn)如下:
#import "PluginOne.h"

@implementation PluginOne

@synthesize mainWindow;

- (id)init
{
    self 
= [super init];
    
if (self) {
        
// Initialization code here.
        
        [NSBundle loadNibNamed:
@"PluginOneMainWindow" owner:self];
    }
    
    
return self;
}

- (void)dealloc
{
    mainWindow 
= nil;

    [super dealloc];
}

- (NSString *)name;
{
    
return @"Plugin One";
}

- (IBAction)run:(id)sender;
{
    [mainWindow center];
    [mainWindow makeKeyAndOrderFront:sender];
}

- (IBAction)closeWindow:(id)sender;
{
    [mainWindow orderOut:sender];
}

@end

5,plugin 設(shè)置
下面我們來對 plugin 進(jìn)行設(shè)置,我們可以設(shè)置其 Principal class,Wrapper Extension(擴(kuò)展名)。


使用 plugin
1,宿主程序設(shè)置
前面說了,在這個例子中,我們打算將插件隨宿主程序一起發(fā)布,所以其存放位置就在宿主應(yīng)用程序包中。因此我們需要在宿主程序種添加一個 Add Copy Files 的 build phase,如下所示:


2,載入plugin
在正式的應(yīng)用中,我們應(yīng)該在前面提到的三個目錄下去查找所有 plugin,因為這三個目錄都是 Cocoa 所推薦的 plugin 目錄。在這個例子中,演示的是隨宿主應(yīng)用程序一起發(fā)布的程序,所以我只掃描了應(yīng)用程序包中的目錄。
- (NSArray *)loadPlugins
{
    NSBundle 
*main = [NSBundle mainBundle];
    NSArray 
*allPlugins = [main pathsForResourcesOfType:@"bundle" inDirectory:@"../PlugIns"];
    
    NSMutableArray 
*availablePlugins = [[[NSMutableArray alloc] init] autorelease];
    
    id plugin 
= nil;
    NSBundle 
*pluginBundle = nil;
    
    
for (NSString *path in allPlugins) {
        pluginBundle 
= [NSBundle bundleWithPath:path];
        [pluginBundle load];
        
        Class principalClass 
= [pluginBundle principalClass];
        
if (![principalClass isSubclassOfClass:[AbstractPlugin class]]) {
            
continue;
        }
        
        plugin 
= [[principalClass alloc] init];
        
        
if ([plugin respondsToSelector:@selector(run:)])
        {
            [availablePlugins addObject:plugin];
            NSLog(
@" >> loading plugin %@ from %@", [plugin name], path);
        }
        
        [plugin release];
        plugin 
= nil;
        pluginBundle 
= nil;
    }

    
return availablePlugins;
}

該函數(shù)在 init 中被調(diào)用:
- (id)init
{
    self 
= [super init];
    
if (self) {
        plugins 
= [[self loadPlugins] retain];
        
//plugins = [[self loadAllPlugins] retain];
    }
    
    
return self;
}

下面提供一個函數(shù)掃描前面提到的三個目錄,你可以用這個函數(shù)提到上面代碼中對 loadPlugins 的調(diào)用:
- (NSArray *)loadAllPlugins
{
    NSString 
*appName       = @"PluginOne/Plugins";
    NSString 
*appSupport    = @"Library/Application Support";
    appSupport              
= [appSupport stringByAppendingPathComponent:appName];

    NSString 
*appPath       = [[NSBundle mainBundle] builtInPlugInsPath];
    NSString 
*userPath      = [NSHomeDirectory() stringByAppendingPathComponent:appSupport];
    NSString 
*sysPath       = [@"/" stringByAppendingPathComponent:appSupport];
    
    NSArray
* paths = [NSArray arrayWithObjects:appPath, userPath, sysPath, nil];
    
    NSMutableArray 
* availablePlugins = [[[NSMutableArray alloc] init] autorelease];
    
for (NSString * path in paths)
    {
        NSLog(
@" >> Search in directory: %@", path);

        NSArray 
*contents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL];
        
for (NSString *fileName in contents)
        {
            
if ( [[fileName pathExtension] isEqualToString:@"plugin"|| [[fileName pathExtension] isEqualToString:@"bundle"])
            {
                NSString 
*fullPath = [path stringByAppendingPathComponent:fileName];
                NSBundle 
*pluginBundle = [NSBundle bundleWithPath:fullPath];
                
if (pluginBundle && [pluginBundle load])
                {
                    Class principalClass 
= [pluginBundle principalClass];
                    
if (![principalClass isSubclassOfClass:[AbstractPlugin class]]) {
                        
continue;
                    }
                    
                    id plugin 
= [[principalClass alloc] init];
                    
                    
if ([plugin respondsToSelector:@selector(run:)])
                    {
                        [availablePlugins addObject:plugin];
                        NSLog(
@" >> loading plugin %@ from %@", [plugin name], path);
                    }
                    
                    [plugin release];
                    plugin 
= nil;
                }
            }
        }
    }
    
    
return availablePlugins;
}

運(yùn)行結(jié)果
顯示 plugin 列表的 popupbutton 的內(nèi)容被綁定到該 plugins 數(shù)組,所以程序啟動之后,就能顯示 plugin 的列表。運(yùn)行結(jié)果如下:


點(diǎn)擊運(yùn)行之后,就能顯示出插件主界面:


Reference
Code Loading Programming Topics provides information about writing plug-ins using the Objective-C language.
Bundle Programming Guide provides an overview to bundles, including their purpose, types, structure, and the API for accessing bundle resources.

posted on 2011-10-28 14:44 羅朝輝 閱讀(2572) 評論(0)  編輯 收藏 引用 所屬分類: Cocoa 開發(fā)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            久久美女性网| 久久国产精品久久久久久电车 | 亚洲国产精品久久人人爱蜜臀 | 中文精品视频| 欧美一区二区久久久| 亚洲黄色高清| 亚洲小说欧美另类社区| 伊人成人网在线看| 9人人澡人人爽人人精品| 国产一区二区三区在线观看免费视频 | 一区二区三区偷拍| 伊人久久大香线蕉av超碰演员| 亚洲国产午夜| 国产一区二区三区奇米久涩 | 亚洲欧洲日产国码二区| 国产精品99久久久久久久女警| 在线观看欧美亚洲| 亚洲一区二区三区四区视频| 亚洲精品久久久久久久久久久久久 | 国产精品一区二区在线观看| 亚洲电影自拍| 黄色日韩在线| 亚洲欧美综合| 亚洲小视频在线观看| 猛干欧美女孩| 久久久久久电影| 国产精品久久久久久一区二区三区 | 欧美~级网站不卡| 久久精品亚洲| 国产女主播在线一区二区| 亚洲精品一级| 亚洲七七久久综合桃花剧情介绍| 午夜伦理片一区| 亚洲欧美另类中文字幕| 国产日韩三区| 一本久久青青| 亚洲日本一区二区| 久久一二三区| 鲁大师影院一区二区三区| 国产一区999| 欧美一二三区精品| 欧美一级片久久久久久久| 欧美性一区二区| 中国av一区| 午夜一区二区三区在线观看| 欧美日韩一区二区免费视频| 亚洲国内精品在线| 亚洲免费高清| 欧美美女喷水视频| 亚洲乱码国产乱码精品精| 一区二区高清视频| 欧美日韩专区| 亚洲影院在线观看| 久久精品99国产精品日本| 国产在线视频不卡二| 久久国内精品视频| 欧美77777| 亚洲理伦在线| 欧美日韩一视频区二区| 亚洲美女福利视频网站| 亚洲视频国产视频| 国产精品久久久久久久午夜片| 一区二区三区欧美激情| 亚洲欧美日韩人成在线播放| 国产精品日韩欧美| 欧美在线国产精品| 国产一区二区三区在线观看免费| 欧美影视一区| 久热综合在线亚洲精品| 一区二区在线视频播放| 麻豆精品在线观看| 亚洲精品一区二区三区四区高清| 亚洲图色在线| 国产欧美二区| 久久这里只有精品视频首页| 亚洲夫妻自拍| 亚洲欧美视频在线观看视频| 国产午夜精品全部视频播放| 久久免费国产精品1| 亚洲欧洲日韩女同| 性色av一区二区三区| 亚洲第一视频| 国产精品久久久久三级| 久久精品一区二区国产| 亚洲人成7777| 久久九九热免费视频| 亚洲精品久久| 国产日韩欧美在线播放| 欧美高清在线视频| 亚洲欧美日韩网| 亚洲欧洲三级| 久久亚洲免费| 亚洲综合三区| 亚洲精品视频免费观看| 国产日韩欧美视频| 欧美日本在线| 久久精品首页| 在线视频一区观看| 亚洲欧美www| 亚洲国产精品激情在线观看| 欧美视频在线观看| 久久亚洲春色中文字幕久久久| 亚洲精选久久| 你懂的成人av| 欧美一区二区精品在线| 久久在线精品| 亚洲综合日韩中文字幕v在线| 国产欧美日韩激情| 欧美极品色图| 久久精品欧美| 亚洲一级电影| 亚洲高清在线视频| 久久人体大胆视频| 午夜视频在线观看一区| 亚洲精品一级| 精东粉嫩av免费一区二区三区| 国产精品久久久久久超碰| 欧美国产日韩视频| 狂野欧美激情性xxxx欧美| 亚洲免费小视频| 夜夜嗨av一区二区三区四区| 亚洲视频视频在线| 亚洲精品无人区| 亚洲国产精品黑人久久久 | 亚洲精品在线免费| 欧美国产乱视频| 久久天天躁狠狠躁夜夜av| 午夜精品美女久久久久av福利| 99国产精品久久久| 亚洲精品一区在线| 亚洲国产精品激情在线观看| 在线不卡视频| 在线不卡中文字幕| 在线免费观看成人网| 一区在线视频| 亚洲电影观看| 亚洲黑丝在线| 亚洲卡通欧美制服中文| 亚洲精品少妇| 亚洲社区在线观看| 亚洲午夜91| 午夜精品一区二区在线观看| 亚洲一区二区三区在线看| 亚洲午夜激情| 欧美一级久久| 久久精品国语| 久久深夜福利| 欧美18av| 亚洲国产综合91精品麻豆| 亚洲精品日韩在线观看| a91a精品视频在线观看| 9人人澡人人爽人人精品| 夜夜夜久久久| 午夜国产一区| 久久在线播放| 欧美理论电影网| 国产精品男gay被猛男狂揉视频| 国产精品久久| 国模精品娜娜一二三区| 原创国产精品91| 亚洲精品免费在线观看| 99国产精品视频免费观看一公开| 亚洲自拍偷拍网址| 久久另类ts人妖一区二区| 欧美高清视频一区二区| 99热这里只有成人精品国产| 亚洲欧美第一页| 久久在线免费| 国产精品男gay被猛男狂揉视频| 黄色成人在线网站| 一区二区免费在线观看| 欧美一区二区三区免费视频| 免费的成人av| 亚洲私拍自拍| 老色鬼久久亚洲一区二区| 欧美视频日韩视频| 伊人成年综合电影网| 亚洲自拍偷拍福利| 欧美激情亚洲| 亚洲欧美日韩天堂| 欧美精品午夜| 国产一区二区三区av电影| 亚洲激情婷婷| 欧美在线免费观看视频| 亚洲福利精品| 亚洲视频你懂的| 在线亚洲国产精品网站| 亚洲一区二区在线观看视频| 久久电影一区| 欧美日韩一区二区三区视频| 国产欧美日韩一区二区三区在线观看 | 亚洲免费在线视频| 免费91麻豆精品国产自产在线观看| 欧美激情一区二区三区在线| 亚洲欧美电影院| 欧美日韩国产成人在线91| 精品不卡视频| 欧美在线二区| 一区二区三区日韩精品视频| 麻豆av一区二区三区久久|