Objective-C是C语言的一种衍生语言,在C语言的基础上加上了面向对象的实现,所以在Objective-C的项目中,对于C语言的支持是全方位的,这就为开发中使用C语言提供了极大的便利.
1. C语言优点
相对于面向对象的高级编程语言而言,C语言具有明显的优点:
- 不依赖于类而存在,可以在任意需要的地方直接调用,省去创建类或者分类的过程;
- 更接近机器语言,执行效率高;
- 面向过程,不需要关注生命周期;
- 实现简洁紧凑,调用方便.
正是基于这些特质,在恰当的时候使用C语言进行功能开发可以更加高效.
2. 使用场景
2.1 脱离对象的方法调用(针对所有对象都可以调用的方法)
在某些使用实现场景中,我们希望方法实现可以脱离对象而单独存在,可以在需要的任何地方进行调用,这时候我们就可以考虑使用C语言的函数来实现.
例如,在使用对象之前,希望确定对象是有效的对象,需要排除注入null, nil等特殊情况以防止异常发生:
BOOL isAvailable(id object) { if ([object isEqual:[NSNull null]]) { return false; } if (! object || object == NULL) { return false; } return true; }
2.2 使用范围很小,没有必要单独创建类或者分类
例如,在某种特定的自定义cell中,我们需要一个文本按照":"分成两部分显示,
static NSString *format(NSString *ori) { NSRange range = [ori rangeOfString:@":"]; NSMutableAttributedString *result = [[NSMutableAttributedString alloc] initWithString:ori]; if (range.location != NSNotFound && range.location < ori.length - 1) { [result addAttributes:@{NSFontAttributeName : [UIFont fontWithName:@"PingFangSC-Bold" size:20.0]} range:(NSRange){0, range.location}]; [result addAttributes:@{NSFontAttributeName : [UIFont fontWithName:@"PingFangSC-Regular" size:15.0]} range:(NSRange){range.location, ori.length - 1}]; } return (NSString *)result; }
2.3 运行时动态替换方法
在进行运行时方法替换时,可以使用C语言的实现来添加自定义操作,同时还可以保存原来的实现在需要的时候进行调用,这样就可以实现交换可以放生在任何位置,而不必约束在需要交换的类中.
例如,在应用启动时替换UIViewController的viewDidLoad方法,添加自定义统计操作,并保存原始的实现:
static void(*orignalImplement)(id, SEL); static void ed_viewDidLoad(id self, SEL cmd) { [EDAnalysisManager loadViewController:NSStringFromClass([self class])]; //如果原始实现存在,调用原始实现 if (orignalImplement) { orignalImplement(self, cmd); } } @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Class destinationClass = [UIViewController class]; Method method = class_getInstanceMethod(destinationClass, @selector(viewDidLoad)); orignalImplement = (typeof(orignalImplement))method_getImplementation(method); method_setImplementation(method, (IMP)ed_viewDidLoad); // Override point for customization after application launch. return YES; }