[精通Objective-C]进阶技巧:使用运行时系统API
参考书籍:《精通Objective-C》【美】 Keith Lee
目录
动态加载可选包
下面是使用NSbundle API动态加载自己编写的框架包的示例,共需要创建两个工程,一个命令行程序和一个可选包。
创建命令行程序:
创建一个协议和一个遵守该协议的类用于测试:
Greeter协议:
#import <Foundation/Foundation.h>
@protocol Greeter <NSObject>
-(NSString *)greeting:(NSString *)salutation;
@end
BasicGreeter类:
#import <Foundation/Foundation.h>
#import "Greeter.h"
@interface BasicGreeter : NSObject <Greeter>
@end
#import "BasicGreeter.h"
@implementation BasicGreeter
-(NSString *) greeting:(NSString *)salutation{
return [NSString stringWithFormat:@"%@,World!",salutation];
}
@end
创建可选包
新建工程中选择OS X->Framework&Library->Bundle:
先将Greeter.h添加到可选包中。再创建一个遵守Greeter协议的类
CustomGreeter类:
#import <Foundation/Foundation.h>
#import "Greeter.h"
@interface CustomGreeter : NSObject <Greeter>
@end
#import "CustomGreeter.h"
@implementation CustomGreeter
-(NSString *)greeting:(NSString *)salutation{
return [NSString stringWithFormat:@"%@,Universe!", salutation];
}
@end
传入包路径
接下需要将可选包的路径作为参数传入命令行程序的main函数中:
选择工程中的bundle文件(记得先编译一次,不然bundle文件是红色的,无法使用),然后将图中标记的bundle文件完整路径复制下来:
回到命令行程序,点击下图中标记处,选择Edit Scheme:
在弹出窗口的下图标记位置粘贴刚刚复制的bundle文件路径:
这样就完成了参数的传入。
使用可选包
最后在main.m中进行测试:
#import <Foundation/Foundation.h>
#import "BasicGreeter.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 声明一个类型为id并且遵循Greeter协议的变量并进行测试
id<Greeter> greeter = [[BasicGreeter alloc] init];
NSLog(@"%@",[greeter greeting:@"Hello"]);
// 在指定路径(通过输入参数获得)创建一个包
NSString *bundlePath;
// argc设置了程序的参数数量,而argv[]数组存储了参数值,数组第一个参数存储了程序的名称,
// 因此argc大于或等于1,这里传递了一个参数(包的路径),所以argc应该等于2.
if (argc != 2) {
// 没有获得包路径,退出
NSLog(@"Please provide a path for the bundle");
}
else{
// 获取包的路径并创建一个NSBundle对象
bundlePath = [NSString stringWithUTF8String:argv[1]];
NSBundle *greeterBundle = [NSBundle bundleWithPath:bundlePath];
if (greeterBundle == nil) {
NSLog(@"Bundle not found at path");
}
else{
// 以动态方式加载包