Xcode裏-ObjC, -all_load, -force_load
之所以使用該標誌,和Objective-C的一個重要特性:類別(category)有關。根據這裏的解釋,Unix的標準靜態庫實現和Objective-C的動態特性之間有一些衝突:Objective-C沒有爲每個函數(或者方法)定義鏈接符號,它只爲每個類創建鏈接符號。這樣當在一個靜態庫中使用類別來擴展已有類的時候,鏈接器不知道如何把類原有的方法和類別中的方法整合起來,就會導致你調用類別中的方法時,出現"selector not recognized",也就是找不到方法定義的錯誤。爲了解決這個問題,引入了-ObjC標誌,它的作用就是將靜態庫中所有的和對象相關的文件都加載進來。
本來這樣就可以解決問題了,不過在64位的Mac系統或者iOS系統下,鏈接器有一個bug,會導致只包含有類別的靜態庫無法使用-ObjC標誌來加載文件。變通方法是使用-all_load 或者-force_load標誌,它們的作用都是加載靜態庫中所有文件,不過all_load作用於所有的庫,而-force_load後面必須要指定具體的文件。
明白了這些,我就清楚,這個第三方庫中一定是定義了一些類別來擴着已有類,打開頭文件,發現果然如此。
#import
@interface MyStaticLibraryDemo : NSObject
/// 加法
- (int)addMethodByFirst:(int)theFirst andSecond:(int)theSecond;
/// 減法
- (int)SubMethodByFirst:(int)theFirst andSecond:(int)theSecond;
@end
#import "MyStaticLibraryDemo.h"
@implementation MyStaticLibraryDemo
/// 加法
- (int)addMethodByFirst:(int)theFirst andSecond:(int)theSecond{
return (theFirst+theSecond);
}
/// 減法
- (int)SubMethodByFirst:(int)theFirst andSecond:(int)theSecond{
return (theFirst-theSecond);
}
@end
bogon:~ zhangzhen$ cd /Users/zhangzhen/Library/Developer/Xcode/DerivedData/MyStaticLibraryDemo-ciwnhcsbqgclkododazbmbmtdlfp/Build/Products/Release-iphoneos
bogon:Release-iphoneos zhangzhen$ lipo -info libMyStaticLibraryDemo.a
Architectures in the fat file: libMyStaticLibraryDemo.a are: armv7 armv7s arm64
bogon:~ zhangzhen$ cd /Users/zhangzhen/Library/Developer/Xcode/DerivedData/MyStaticLibraryDemo-ciwnhcsbqgclkododazbmbmtdlfp/Build/Products/Release-iphonesimulator
bogon:Release-iphonesimulator zhangzhen$ lipo -info libMyStaticLibraryDemo.a
Architectures in the fat file: libMyStaticLibraryDemo.a are: i386 x86_64
MyStaticLibraryDemo *myLibrary=[[MyStaticLibraryDemo alloc] init];
int result= [myLibrary addMethodByFirst:5 andSecond:5];
NSLog(@"Result:%d",result);
result=[myLibrary SubMethodByFirst:10 andSecond:5];
NSLog(@"Result:%d",result);
ld: warning: ignoring file /Users/XXXX/Documents/MyLibraryTest/MyLibraryTest/MyLibrary/libMyStaticLibraryDemo.a, missing required architecture i386 in file/Users/XXXX/Documents/MyLibraryTest/MyLibraryTest/MyLibrary/libMyStaticLibraryDemo.a (3 slices)
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_MyStaticLibraryDemo", referenced from:
objc-class-ref in AppDelegate.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
bogon:~ zhangzhen$ lipo -create /所在路徑/Release-iphoneos/libMyStaticLibraryDemo.a /所在路徑/Release-iphonesimulator/libMyStaticLibraryDemo.a -output /Users/zhangzhen/Desktop/libUniversal.a
bogon:~ zhangzhen$