一个静态库框架模板: iOS Universal Framework Mk 7
項目地址:?https://github.com/kstenerud/iOS-Universal-Framework
?
這是一個Xcode 4使用的項目模板,而不是一個新的開源框架。
?
這是項目主頁,介紹得很清楚,我把它抓過來翻譯了一下。
?
我們為什么需要框架(Framework)?
要想用一種開發者友好的方式共享庫是很麻煩的。你不僅僅需要包含庫本身,還要加入所有的頭文件,資源等等。
蘋果解決這個問題的方式是框架(framework)?;旧?#xff0c;這是含有固定結構并包含了引用該庫時所必需的所有東西的文件夾。不幸的是,iOS禁止所有的動態庫。同時,蘋果也從Xcode中移除了創建靜態iOS框架的功能。
Xcode仍然可以支持創建框架的功能,重啟這個功能,我們需要對Xcode做一些小小的改動。
把代碼封裝在靜態框架是被app store所允許的。盡管形式不同,本質上它仍然是一種靜態庫。
框架(Framework)的類別
大部分框架都是動態鏈接庫的形式。因為只有蘋果才能在iOS設備上安裝動態庫,所以我們無法創建這種類型的框架。
靜態鏈接庫和動態庫一樣,只不過它是在編譯時鏈接二進制代碼,因此使用靜態庫不會有動態庫那樣的問題(即除了蘋果誰也不能在iOS上使用動態庫)。
“偽”框架是通過破解Xcode的目標Bundle(使用某些腳本)來實現的。它在表面上以及使用時跟靜態框架并無區別?!皞巍笨蚣茼椖康墓δ軒缀鹾驼鎸嵉目蚣茼椖繘]有區別(不是全部)。
“嵌入”框架是靜態框架的一個包裝,以便Xcode能獲取框架內的資源(圖片、plist、nib等)。
本次發布包括了創建靜態框架和“偽”框架的模板,以及二者的“嵌入”框架。
用哪一種模板?
本次發布有兩個模板,每個模板都有“強”“弱”兩個類別。你可以選擇最適合一種(或者兩種都安裝上)。
最大的不同是Xcode不能創建“真”框架,除非你安裝靜態框架文件xcspec在Xcode中。這真是一個遺憾(這個文件是給項目使用的,而不是框架要用的)。
簡單第
簡單說,你可以這樣決定用哪一種模板:
- 如果你不想修改Xcode,那么請使用“偽”框架版本
- 如果你只是想共享二進制(不是項目),兩種都可以
- 如果你想把框架共享給不想修改Xcode的開發者,使用“偽”框架版本
- 如果你想把框架共享給修改過Xcode的開發者,使用“真”框架版本
- 如果你想把框架項目作為另一個項目的依賴(通過workspace或者子項目的方式),請使用“真”框架(或者“偽”框架,使用-framework——見后)
- 如果你想在你的框架項目中加入其他靜態庫/框架,并把它們也鏈接到最終結果以便不需要單獨添加到用戶項目中,使用“偽”框架
“偽”框架
“偽”框架是破解的“reloacatable object file”(可重定位格式的目標文件, 保存著代碼和數據,適合于和其他的目標文件連接到一起,用來創建一個可執行目標文件或者是一個可共享目標文件),它可以讓Xcode編譯出類似框架的東西——其實也是一個bundle。
“偽框架”模板把整個過程分為幾個步驟,用某些腳本去產生一個真正的靜態框架(基于靜態庫而不是reloacatable object file)。而且,框架項目還是把它定義為wrapper.cfbundle類型,一種Xcode中的“二等公民”。
因此它跟“真”靜態框架一樣可以正常工作,但當存在依賴關系時就有麻煩了。
依賴問題
如果不使用依賴,只是創建普通的項目是沒有任何問題的。但是如果使用了項目依賴(比如在workspace中),Xcode就悲劇了。當你點擊“Link Binary With Libraries”下方的’+’按鈕時,“偽框架”無法顯示在列表中。你可以從你的“偽”框架項目的Products下面將它手動拖入,但當你編輯你的主項目時,會出現警告:
warning: skipping file '/somewhere/MyFramework.framework' (unexpectedfile type 'wrapper.cfbundle' in Frameworks & Libraries build phase)
并伴隨“偽”框架中的鏈接錯誤。
幸運的是,有個辦法來解決它。你可以在”Other Linker Flags”中用”-framwork”開關手動告訴linker去使用你的框架進行鏈接:
-framework MyFramework
警告仍然存在,但起碼能正確鏈接了。
添加其他的庫/框架
如果你加入其他靜態(不是動態)庫/框架到你的“偽”框架項目中,它們將“鏈接”進你最終的二進制框架文件中。在“真”框架項目中,它們是純引用,而不是鏈接。
你可以在項目中僅僅包含頭文件而不是靜態庫/框架本身的方式避免這種情況(以便編譯通過)。
“真”框架
“真”框架各個方面都符合“真”的標準。它是真正的靜態框架,正如使用蘋果在從Xcode中去除的那個功能所創建的一樣。
為了能創建真正的靜態框架項目,你必需在Xcode中安裝一個xcspec文件。
如果你發布一個“真”框架項目(而不是編譯),希望去編譯這個框架的人必需也安裝xcspec文件(使用本次發布的安裝腳本),以便Xcode能理解目標類型。
注意:如果你正在發布完全編譯的框架,而不是框架項目,最終用戶并不需要安裝任何東西。
我已經提交一個報告給蘋果,希望他們在Xcode中更新這個文件,但那需要一點時間.OpenRadarlink here
加其他靜態庫/框架
如果你加入其他靜態(不是動態)庫/框架到你的“真”框架項目,它們只會被引用,而不會象“偽”框架一樣被鏈接到最終的二進制文件中。
從早期版本升級
如果你是從Mk6或者更早的版本升級,同時使用“真”靜態框架,并且使用Xcode4.2.1以前的版本,請運行uninstall_legacy.sh以卸載早期用于Xcode的所有修正。然后再運行install.sh,重啟Xcode。如果你使用Xcode4.3以后,只需要運行install.sh并重啟Xcode。
安裝
分別運行Real Framework目錄或Fake Framework目錄下的install.sh腳本進行安裝(或者兩個你都運行)。
重啟Xcode,你將在新項目向導的Framework&Library下看到StaticiOS Framework(或者Fake Static iOS Framework)。
卸載請運行unistall.sh腳本并重啟Xcode。
創建一個iOS框架項目
編譯你的 iOS 框架
在build目錄下有兩個文件夾:(yourframework).framework?and?(your framework).embeddedframework.
如果你的框架只有代碼,沒有資源(比如圖片、腳本、xib、coredata的momd文件等),你可以把(yourframework).framework?分發給你的用戶就行了。如果還包含有資源,你必需分發(your framework).embeddedframework給你的用戶。
為什么需要embedded framework?因為Xcode不會查找靜態框架中的資源,如果你分發(your framework).framework, 則框架中的所有資源都不會顯示,也不可用。
一個embedded framework只是一個framework之外的附加的包,包括了這個框架的所有資源的符號鏈接。這樣做的目的是讓Xcode能夠找到這些資源。
使用iOS 框架
iOS框架和常規的Mac OS動態框架差不多,只是它是靜態鏈接的而已。
在你的項目中使用一個框架,只需把它拖僅你的項目中。在包含頭文件時,記住使用尖括號而不是雙引號括住框架名稱。例如,對于框架MyFramework:
#import <MyFramework/MyClass.h>
使用問題
Headers Not Found
如果Xcode找不到框架的頭文件,你可能是忘記將它們聲明為public了。參考“創建一個iOS框架項目”第5步。
No Such Product Type
如果你沒有安裝iOS Universal Framework在Xcode,并企圖編譯一個universal框架項目(對于“真”框架,不是“假”框架),這會導致下列錯誤:
target specifies product type 'com.apple.product-type.framework.static',but there's no such product type for the 'iphonesimulator' platform
為了編譯“真”iOS靜態框架,Xcode需要做一些改動,因此為了編譯“真”靜態框架項目,請在所有的開發環境中安裝它(對于使用框架的用戶不需要,只有要編譯框架才需要)。
The selected run destination is not valid for this action
有時,Xcode出錯并加載了錯誤的active設置。首先,請嘗試重啟Xcode。如果錯誤繼續存在,Xcode產生了一個壞的項目(因為Xcode4的一個bug,任何類型的項目都會出現這個問題)。如果是這樣,你需要創建一個新項目重來一遍。
鏈接警告
第一次編譯框架target時,Xcdoe會在鏈接階段報告找不到文件夾:
ld: warning: directory not found for option'-L/Users/myself/Library/Developer/Xcode/DerivedData/MyFramework-ccahfoccjqiognaqraesrxdyqcne/Build/Products/Debug-iphoneos'
此時,可以clean并重新編譯target,警告會消除。
Core Data momd not found
對于框架項目和應用程序項目,Xcode會以不同的方式編譯momd(托管對象模型文件)。Xcode會簡單地在根目錄創建.mom文件,而不會創建一個.momd目錄(目錄中包含VersionInfo.plist和.mom文件)。
這意味著,當從一個embedded framework的model中實例化NSManagedObjectModel時,你必需使用.mom擴展名作為model的URL,而不是采用.momd擴展名。
NSURL *modelURL = [[NSBundle mainBundle]URLForResource:@"MyModel" withExtension:@"mom"];
Unknown class MyClass in Interface Builder file.
由于靜態框架采用靜態鏈接,linker會剔除所有它認為無用的代碼。不幸的是,linker不會檢查xib文件,因此如果類是在xib中引用,而沒有在O-C代碼中引用,linker將從最終的可執行文件中刪除類。這是linker的問題,不是框架的問題(當你編譯一個靜態庫時也會發生這個問題)。蘋果內置框架不會發生這個問題,因為他們是運行時動態加載的,存在于iOS設備固件中的動態庫是不可能被刪除的。
有兩個解決的辦法:
在MyTextField中:
+ (void)forceLinkerLoad_ {}
在MyViewController中:
+(void) initialize { ????[MyTextField forceLinkerLoad_]; }
他們仍然需要添加-ObjC到linker設置,但不需要強制all_load了。
第2種方法需要你多做一點工作,但卻讓最終用戶避免在使用你的框架時關閉linker優化(關閉linker優化會導致object文件膨脹)。
unexpected file type 'wrapper.cfbundle' in Frameworks &Libraries build phase
這個問題發生在把“假”框架項目作為workspace的依賴,或者把它當作子項目時(“真”框架項目沒有這個問題)。盡管這種框架項目產生了正確的靜態框架,但Xcode只能從項目文件中看出這是一個bundle,因此它在檢查依賴性時發出一個警告,并在linker階段跳過它。
你可以手動添加一個命令讓linker在鏈接階段能正確鏈接。在依賴你的靜態框架的項目的OtherLinker Flags中加入:
-framework MyFramework
警告仍然存在, 但不會導致鏈接失敗。
Libraries being linked or not being linked into the finalframework
很不幸, “真”框架和“假”框架模板在處理引入的靜態庫/框架的工作方式不同的。
“真”框架模板采用正常的靜態庫生成步驟,不會鏈接其他靜態庫/框架到最終生產物中。
“假”框架模板采用“欺騙”Xcode的手段,讓它認為是在編譯一個可重定位格式的目標文件,在鏈接階段就如同編譯一個可執行文件,把所有的靜態代碼文件鏈接到最終生成物中(盡管不會檢查是否確實目標代碼)。為了實現象“真”框架一樣的效果,你可以只包含庫/框架的頭文件到你的項目中,而不需要包含庫/框架本身。
Unrecognized selector in (some class with a category method)
如果你的靜態庫或靜態框架包含了一個模塊(只在類別代碼中聲明,沒有類實現),linker會搞不清楚,并把代碼從二進制文件中剔除。因為在最終生成的文件中沒有這個方法,所以當調用這個類別中定義的方法時,會報一個“unrecognizedselector”異常。
要解決這個,在包含這個類別的模塊代碼中加一個“假的”類。linker發現存在完整的O-C類,會將類別代碼鏈接到模塊。
我寫了一個頭文件?LoadableCategory.h,以減輕這個工作量:
#import "SomeConcreteClass+MyAdditions.h"
#import "LoadableCategory.h"??MAKE_CATEGORIES_LOADABLE(SomeConcreteClass_MyAdditions);?? @implementation SomeConcreteClass(MyAdditions)
? ...?
@end
在使用這個框架時,仍然還需要在Build Setting的Other Linker Flags中加入-ObjC。
執行任何代碼前單元測試崩潰
?
?
?
?
http://blog.csdn.net/jason20ming/article/details/7487139
今天看了一天關于Static Library以及Static Frame的相關資料,先記下來,以免忘了。
跟大多數操作系統相同,Mac OS X及iOS上均支持靜態鏈接庫和動態鏈接庫(這樣說可能有點不恰當,但是都是這個意思附近的了)
在Xcode 4.3中如果是新建一個Mac OS X的項目,可以看見“Framework & Library”內有各種各樣的Library及Framework的模板,當然,這些都可以是靜態鏈接或者動態鏈接的。
但是如果新建的是iOS的項目,在“Framework ?& Library”內的模板就少得可憐,就只有一個“Cocoa Touch Static Library”,顧名思義就是一個靜態鏈接庫模板。
靜態鏈接庫用起來的頗為麻煩,libxml2就是一個例子,首先要加入linker內讓linker找到符號,然后還需要配置Header讓compiler可以找到這些符號的定義?;谶@種不人性化操作,蘋果在自己的平臺上推出了一種新的引用方式,那就是Framework。
Framework其實就是將Header及Library打包在一起方便使用,在蘋果的官方文檔,Framework還可以嵌套打包,其稱為Umbrella Framework,不過其不建議普通用戶這樣做而已。我們平常使用的QuartzCore、UIKit、CoreFoundation等均打包為Framework。
可惜的是,因為沒有模板,所以不能簡單地創建一個Framework,但是一個開源的模板項目可以幫到我們:iOS-Universal-Framework。
這個模板分開兩塊:Fake Static Framework 和 Real Static Framework,安裝及使用方法在github上的項目有詳細教程(其實很簡單,運行一個腳本就OK)。
看到名字開始會很疑惑,這東西還能有Fake和Real的?
原來,蘋果出于某種原因的考慮,在Xcode上禁用了iOS項目引入非官方Framework的功能,所以這里的Framework分成了兩種。
Fake的是通過一個bundle模擬Framework,這個不需要對Xcode進行任何改動,只需要添加一個項目模板即可,但是使用這個模板并且開啟ARC時候會出現問題,這個后面會說道。
Real的生成出來的product就是一個真真正正的Framework,但是由于Xcode不支持在iOS上使用自定義Framework,所以需要向Xcode內加入兩個xcspec文件以啟用支持。
將兩個模板都安裝完成后,可以看見iOS中的“Framework & Library”多出了兩個Framework的模板??纯疵?#xff0c;里面均有一個“Static”,這表示生成的Framework都是靜態的,因為蘋果是禁止開發者向iOS內添加動態庫的,這樣就可以保證所有應用的依賴均來源于蘋果內部,降低開發難度也可以保證應用不會因為缺少依賴庫而Crash。所以,無論Static Framework或者Static Library,最終所有的符號均會被內聯到程序中,跟直接在項目內編寫代碼是一樣的。
既然生成的二進制都是一樣的,為什么還要提取一個庫出來呢?雖然iOS上二進制是不可共享的,但是代碼是可以共享的,可以將經常使用的組件提出成一個公共庫,再供給程序使用,這樣可以有效減低程序內的代碼量。(說離題了。。。)
下面說說 Static Library、Fake Static Framework、Real Static Framework 使用需要注意的事項以及其優劣,特別是在Deployment Target 在 iOS 5.0以下時候容易出現的問題。
?
Static Library:
簡單的靜態鏈接庫,其使用Libtool生成靜態鏈接庫文件,不會因為開啟iOS 4.0以下版本的ARC而強制將libarclite鏈接至靜態鏈接庫;但是,其使用較為麻煩,不方便發布。
Static Library在生成的靜態庫時候會加上一個參數-arch_only armv7(使用模擬器時是:-arch_only i386),即使這個庫只可用于模擬器或者真實設備,現在貌似暫時沒有辦法設置其同時支持armv7和i386。
?
Fake Static Framework:
這個不是一個真正的Framework,實際類型是Core Foundation Bundle,所以叫做Fake Framework。
因為其生成的目標是CFBundle,所以Xcode使用Ld命令生成目標靜態庫,這樣在工程內的Link Binary with Libraries不能有系統的Framework和Library,一旦引入系統的庫,Ld命令會將引入庫的所有符號內聯到當前工程中,當其它工程引用這個靜態庫的時候就會出現Duplicate symbol define的錯誤!
基于這個原因,在Deployment Target低于5.0而且開啟ARC的時候可能會出現Duplicate symbol define: objc_retainObject()的錯誤,出現這個錯誤的原因如下:
1. Fake Static Framework使用Ld命令生成庫,而不是使用Libtool生成庫,當Framework工程的Deployment Target低于5.0而且開啟ARC的時候編譯器會向程序寫入內存管理方面的代碼,而Ld命令會將libarclite庫內對應的函數(如objc_retainObject())的定義加入到當前的靜態庫中。
2. 在引用Framework的工程中,如果Deployment Target低于5.0而且開啟ARC,同1道理,Ld命令會向項目內引入libarclite庫并將定義加入當前項目,但是由于在引入的Framework中已經包含有相關符號,所以會出現Duplicate symbol define。
解決方案如下:在Fake Static Framework生成的時候將Deployment Target改為5.0或更高,在編寫代碼的時候將其改回對應版本(因為5.0以下的不支持weak關鍵字,改回低版本有利于IDE的提示);或者將引用Framework的工程的Deployment Target改為5.0或更高,但是這樣則會失去對低版本的支持。
?
Real Static Framework:
這個是一個真正的Framework,其生成的文件實際類型就是Framework。其內部包含的靜態庫是由Libtool生成的,所以不存在ARC的問題,而且可以在Link Binary with Libraries中加入系統的Framework,其只會在生成的庫中加入對應Framework或Library的引用,而不會將定義也加入其中。
但是,由于蘋果的限制,Xcode不支持Real Static Framework直接引用,需要加入兩個xcspec文件才可以使用,但是使用這個方式的Framework會將不會存在上述兩個靜態庫的n問題,是現時來說最方便的庫。
?
如果你在Xcode4.3中創建靜態框架(或庫)target時,勾選了“withunit tests”,當你試圖運行單元測試時,它會崩潰:
Thread 1: EXC_BAD_ACCESS (code=2, address=0x0) 0 0x00000000 --- 15 dyldbootstrap:start(...)
這是lldb中的一個bug。你可以用GDB來運行單元測試。編輯scheme,選擇Test,在Info標簽中將調試器Debugger從LLDB改為GDB。
?
?
?
?
?
http://spin.atomicobject.com/2011/12/13/building-a-universal-framework-for-ios/
Apple has invested quite a bit of time into making it easy to compile for a number of different architectures in XCode. For instance, compiling a library into its?armv6,?armv7, and?i386variants is just a matter of specifying the supported architecture types. However, there isn’t a built-in mechanism to take the binaries built for the various architectures and merge them into a universal iOS?framework.
Before we go through the steps of building a universal iOS framework we should first reviewwhat?a framework is and?why?they are useful.
?
What is a ‘framework’ and why are they useful?
Apple defines a framework as:
… a hierarchical directory that encapsulates shared resources, such as a dynamic shared library, nib files, image files, localized strings, header files, and reference documentation in a single package.So instead of having header files and binaries in disperate locations a?framework?brings everything together into one package (a directory with a known structure). Packaging a library as a framework simplifies things for developers because it not only provides a binary to link against but it includes all of the necessary header files to reference as well.
What is a ‘universal’ framework?
A universal framework can be defined as a framework that contains a binary which has been built for a number of architectures (armv6, armv7, i386) and can be?statically1?linked against. This is particularly useful in iOS development because an application can be built for the simulator (i386) and the device (armv6, armv7).
1?Statically linking a library resolves symbols at compile time and embeds the library into the application. It is not possible, currently, to create a dynamic framework for iOS.
Building a ‘universal’ framework
Firstly, there is a project called?iOS Universal Framework?that simplifies the process of building a universal framework by providing an XCode template. However, I think it is still a meaningful exercise to understand?how?a universal framework is built using XCode.
Lets get started:
Create a new project
Configure architectures
By default the static library is configured to only build for armv7 so we need to add armv6 and i386 to ensure that the static library is built for older devices (iPhone 3G/Original, early generation iPod Touch) and the simulator.
?
?
Create aggregate target
An aggregate target aggregates other targets together. In effect, it wraps a number of script executables and copy file tasks in a specified order.
?
Build static libraries
Under the “Build Phases” section of the aggregate target we are going to add a build phase that compiles a static library for i386 and?ARM. In the next step we’ll merge the binaries into a fat binary.
?
?
xcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphonesimulator -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphonesimulatorxcodebuild -project ${PROJECT_NAME}.xcodeproj -sdk iphoneos -target ${PROJECT_NAME} -configuration ${CONFIGURATION} clean build CONFIGURATION_BUILD_DIR=${BUILD_DIR}/${CONFIGURATION}-iphoneosThis Gist?brought to you by?GitHub.
?
Build universal binary
We are going to add another “Run Script” phase that builds the framework itself. The script is going to:
Create a directory structure that mimics the same directory structure seen in Apple’s dynamic frameworks:
?
SIMULATOR_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator/lib${PROJECT_NAME}.a" && DEVICE_LIBRARY_PATH="${BUILD_DIR}/${CONFIGURATION}-iphoneos/lib${PROJECT_NAME}.a" && UNIVERSAL_LIBRARY_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneuniversal" && UNIVERSAL_LIBRARY_PATH="${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}" && FRAMEWORK="${UNIVERSAL_LIBRARY_DIR}/${PRODUCT_NAME}.framework" &&?
# Create framework directory structure. rm -rf "${FRAMEWORK}" && mkdir -p "${UNIVERSAL_LIBRARY_DIR}" && mkdir -p "${FRAMEWORK}/Versions/A/Headers" && mkdir -p "${FRAMEWORK}/Versions/A/Resources" &&This Gist?brought to you by?GitHub.
?
Merge the static libraries built for the various architectures into a fat binary using a tool calledlipo:
?
# Generate universal binary for the device and simulator. lipo "${SIMULATOR_LIBRARY_PATH}" "${DEVICE_LIBRARY_PATH}" -create -output "${UNIVERSAL_LIBRARY_PATH}" &&This Gist?brought to you by?GitHub.
?
Move the appropriate files into place:
?
# Move files to appropriate locations in framework paths. cp "${UNIVERSAL_LIBRARY_PATH}" "${FRAMEWORK}/Versions/A" && ln -s "A" "${FRAMEWORK}/Versions/Current" && ln -s "Versions/Current/Headers" "${FRAMEWORK}/Headers" && ln -s "Versions/Current/Resources" "${FRAMEWORK}/Resources" && ln -s "Versions/Current/${PRODUCT_NAME}" "${FRAMEWORK}/${PRODUCT_NAME}"This Gist?brought to you by?GitHub.
?
The full script can be found?here.
Copy header files into place
?
Configure aggregate target build against the ‘Release’ configuration
?
Build and verify framework
Verify that the binary was built for the correct architectures using lipo:
?
lipo -info build/Release-iphoneuniversal/MyLibrary-iOS.framework/MyLibrary-iOS Architectures in the fat file: build/Release-iphoneuniversal/MyLibrary-iOS.framework/MyLibrary-iOS are: i386 armv6 armv7 This Gist?brought to you by?GitHub. Ensure that the header files are copied into place (XCode is known to mess this up on occasion): tree build/Release-iphoneuniversal/MyLibrary-iOS.framework/ build/Release-iphoneuniversal/MyLibrary-iOS.framework/ ├── Headers -> Versions/Current/Headers ├── MyLibrary-iOS -> Versions/Current/MyLibrary-iOS ├── Resources -> Versions/Current/Resources └── Versions ├── A │?? ├── Headers │?? │?? └── MyLibrary.h │?? ├── MyLibrary-iOS │?? └── Resources └── Current -> A 7 directories, 3 files This Gist?brought to you by?GitHub.Conclusion
Creating a universal framework certainly requires a fair amount of upfront work. However, it is a great mechanism to distribute your library to the masses without making?them?work to use it. There is not any configuration (header paths) or tweaking (warnings,?ARC?vs non-ARC?files) required on the part of the user. Which means less work for?you?having to respond to issues and complaints.
Update 02/07/2012:?I’ve updated the scripts to ensure that they work when XCode is configured to choose the build directory (derived). The “Build static libs” script is the one that must be updated.
總結
以上是生活随笔為你收集整理的一个静态库框架模板: iOS Universal Framework Mk 7的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据中心扩张和产能计划
- 下一篇: WordPress 自定义插件初始化及卸