Aug. 7, 2009
前陣子 duckseven 分享了一篇文章 [軟體] 挑戰 OS X 圖示最簡單抓取法,提到這裡有個很厲害的技巧,可以瞬間得到 icns 檔。因為實在太酷了,沒多久 MacUknow 也特地為這一招寫了一篇文章。
Mac OS X 的剪貼簿一直都有驚人的功能,例如可以在 Finder 檔案的「簡介」裡面用複製貼上改圖示等等。但一直以來我的問題是,這個技巧到底是從哪裡來的?為什麼一個剪貼功能可以搞得這麼厲害?
最近在聽 CocoaCast 學 Cocoa Programming,今天學了關於剪下拷貝貼上功能的實作,我終於把這件事情搞懂了,所以來試著解釋一下。
Mac OS X 的剪貼簿是由一個系統伺服來管理,如果打開活動監視器,裡面會有個 pboard 程序就是。當應用程式實作拷貝(或剪下,下同)時,應用程式會對剪貼簿宣告它可以把現在選取的這個項目製作成哪些種類(例如字串、或者 pdf 和 jpg 等等),並把每個種類的檔案全都丟到伺服上面給大家用。
當另一個應用程式(或者同一個應用程式)需要貼上時,這個應用程式就會去問剪貼簿現在有哪些資料種類可以拿,然後把他最喜歡的對應檔案拿回來用。
在實作的時候,剪貼簿可以處理字串(NSString)和資料(NSData)。前者很簡單,應該是為了方便和執行效率所以單獨拿出來;後者提供的資料其實和實作存檔時所提供的一模一樣。所以把資料複製到剪貼簿上這件事,其實可以想成把資料「存檔」在一個虛擬的位置,需要時再從那裡「讀取」。
回到 Finder 的話題,為什麼它可以把「檔案」拷貝到預覽程式,但貼上(*註)時卻會是圖示檔?大概就是因為 Finder 在使用者按下「拷貝」時,會對剪貼簿伺服宣告很多種格式,其中當然包括檔案本身,但還包括例如字串(檔案的 POSIX 位置和 alias,從 Finder 把檔案拖拉放到純文字編輯器時會用到)、圖示(檔案的 icns 檔,本篇主題會用到)等等,所以當預覽程式要求「從剪貼簿新增檔案」時,就會向剪貼簿要求 icns,因此得到我們之前拷貝檔案擁有的圖示檔。
註:對不知道的人,Mac OS X 無法把檔案剪下,只能用拖拉放,這據說是某種安全措施。另外,這兩個行為效果雖然類似,但其實是經由不同的管道,剪下貼上是從剪貼簿伺服中的 general pasteboard,而拖拉放是從同一個伺服裡的另一個剪貼簿,叫做 drag pasteboard。
事實上事情應該比這個還複雜,因為 Cocoa 裡面並沒有 NSICNSPboardType 這個東西可以宣告,所以 Finder 應該還動了一些手腳,例如自製 custom type(這個有文件)之類的。但基本的道理是這樣沒錯,至少我覺得應該是這樣啦。XD
而 Finder 究竟提供了幾種格式給剪貼簿,這就要實驗才知道。可以確定的是,以後我們做這種剪下拷貝貼上動作時應該還可以再無腦一點,然後預期系統會幫我們把該做的轉換都轉好! =P