iOS开发基础-通过C++快速掌握Objective-C语言(进阶)

555 阅读4分钟

本文通过与C++语言对比,介绍Objective-C语言进阶特性。适合具备C++语言基础的程序员快速掌握Object-C语言。

一、内存管理机制

对象生命周期

Objective-C ARC

// 强引用:对象存活期间始终持有
NSObject *obj = [[NSObject alloc] init]; 

// 弱引用:不会阻止对象释放(对象释放后自动置nil)
__weak NSObject *weakRef = obj;

// 自动释放池:延迟释放临时对象
@autoreleasepool {
    NSString *temp = [NSString stringWithFormat:@"%d", 42];
    // temp会在池释放时收到release消息
}
  • 核心原理:编译器自动在合适位置插入retain/release调用
  • 循环引用解法:使用__weak打破相互强引用(类似C++的weak_ptr)

C++智能指针

// 共享所有权(引用计数)
std::shared_ptr<MyClass> p1 = std::make_shared<MyClass>();

// 观察而不持有
std::weak_ptr<MyClass> p2 = p1; 
  • RAII机制:对象析构时自动释放资源
  • 独有所有权unique_ptr禁止复制,只能移动所有权

二、核心特性对比

动态消息转发

触发场景:当对象收到未实现的方法调用时

[obj undefinedMethod]; // 该方法未在类中声明或实现

Objective-C提供三级处理机制(对比C++直接编译报错),避免程序崩溃。


三级处理流程

  1. 动态方法解析
    程序员介入方式
+ (BOOL)resolveInstanceMethod:(SEL)sel {
    if (sel == @selector(undefinedMethod)) {
        // 动态添加C函数作为实现
        class_addMethod(self, sel, (IMP)dynamicIMP, "v@:"); 
        return YES;
    }
    return [super resolveInstanceMethod:sel];
}

底层原理
Runtime系统首次发现方法未实现时,调用此方法注入新实现(类似C++的运行时函数注册)。


  1. 快速消息转发
    程序员介入方式
- (id)forwardingTargetForSelector:(SEL)aSelector {
    if ([_delegate respondsToSelector:aSelector]) {
        return _delegate; // 转交其他对象处理
    }
    return [super forwardingTargetForSelector:aSelector];
}

应用场景

  • 实现简单代理模式
  • 模拟多重继承(类似C++中通过组合对象实现多继承效果)

  1. 完整消息转发
    程序员介入方式
// 步骤1:生成方法签名  
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
    return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}

// 步骤2:处理完整调用  
- (void)forwardInvocation:(NSInvocation *)anInvocation {
    if ([_backupObj respondsToSelector:anInvocation.selector]) {
        [anInvocation invokeWithTarget:_backupObj]; // 完整转发
    } else {
        [super forwardInvocation:anInvocation]; // 触发崩溃
    }
}

能力扩展

  • 修改方法参数/返回值
  • 记录调用日志(类似C++的AOP切面编程)
  • 实现方法调用重试机制

对比C++异常捕获

特性Objective-CC++
动态性支持三级消息转发机制虚函数表静态绑定
错误处理运行时动态修正编译期类型检查
典型应用热修复/方法交换模板元编程/CRTP

实际应用场景示例

崩溃防护

- (void)forwardInvocation:(NSInvocation *)invocation {
    NSLog(@"拦截未实现方法:%@", NSStringFromSelector(invocation.selector));
    // 可在此处上报异常,不触发崩溃
}

动态代理实现

- (id)forwardingTargetForSelector:(SEL)aSelector {
    if ([_networkDelegate respondsToSelector:aSelector]) {
        return _networkDelegate; // 将网络方法转交专门对象
    }
    return [super forwardingTargetForSelector:aSelector];
}

错误处理

Objective-C NSError模式

NSError *error;
BOOL success = [data writeToFile:path options:0 error:&error];

if (!success) {
    NSLog(@"操作失败:%@", error.localizedDescription);
    // 处理错误,而不是崩溃
}
  • 特点:通过指针传递错误对象,与返回值配合使用

C++异常处理

try {
    FileWriter writer("data.bin");
    writer.write(data);
} catch (const FileException& e) {
    std::cerr << "文件错误:" << e.what() << std::endl;
}
  • 特点:通过抛出异常中断正常流程

三、扩展机制

Objective-C分类(Category)

  • 作用:为现有类添加新方法,无需子类化;
  • 限制:不能添加实例变量(可通过关联对象解决) 语法结构
// 声明(ClassName+Feature.h)
@interface NSString (URLEncoding)  // (URLEncoding)为分类名称
- (NSString *)urlEncodedString;    // 新增方法声明
@end

// 实现(ClassName+Feature.m)
@implementation NSString (URLEncoding)
- (NSString *)urlEncodedString {
    return [self stringByAddingPercentEncodingWithAllowedCharacters:
            [NSCharacterSet URLQueryAllowedCharacterSet]];
}
@end

// 使用
NSString *query = @"name=张三";
NSString *encoded = [query urlEncodedString];
  • @interface NSString (URLEncoding):这表示你将为 NSString 类创建一个名为 URLEncoding 的分类。
  • 在分类中,你声明了一个新的方法 - (NSString *)urlEncodedString,这个方法用于对 NSString 对象进行 URL 编码。

C++近似实现

namespace StringExtensions {
    std::string urlEncode(const std::string &s) {
        // 实现编码逻辑
        return encodedStr;
    }
}

// 使用
auto encoded = StringExtensions::urlEncode("name=张三");

四、特殊语法结构

Block语法

基本用法

// 声明:返回值(^块名称)(参数类型)
void (^simpleBlock)(void) = ^{
    NSLog(@"这是一个无参Block");
};

// 调用
simpleBlock();

// 带参数的Block
int (^addBlock)(int, int) = ^(int a, int b) {
    return a + b;
};
NSLog(@"结果:%d", addBlock(3, 5));

// 避免循环引用
__weak typeof(self) weakSelf = self;
self.completionHandler = ^{
    __strong typeof(weakSelf) strongSelf = weakSelf;
    [strongSelf doSomething];
};

对比C++ Lambda

auto lambda = []() { std::cout << "Lambda" << std::endl; };
auto addLambda = [](int a, int b) { return a + b; };

五、混合编程

C语言交互

直接调用C函数

// 定义C函数
void c_print(const char *message) {
    printf("%s\n", message);
}

// Objective-C调用
- (void)logMessage:(NSString *)msg {
    c_print([msg UTF8String]); // NSString转C字符串
}

内存管理注意点

// Core Foundation对象桥接
CFArrayRef cfArray = CFArrayCreate(...);
NSArray *nsArray = (__bridge_transfer NSArray *)cfArray; // 转移所有权