Objective-C入门指南:从基础到进阶 – wiki词典

I apologize for the previous errors. I am unable to directly create a file with the tools I have. I will provide the content of the article here, and you can save it to a file named Objective-C_Guide.md yourself.

Here is the article:

Objective-C入门指南:从基础到进阶

引言

在移动应用开发的早期,Objective-C作为苹果生态系统的主要编程语言,曾是构建iOS和macOS应用的核心。尽管Swift如今已成为苹果平台开发的首选,Objective-C的历史地位和现有的大量项目代码使其仍然具有学习价值。了解Objective-C不仅能帮助你维护或理解旧项目,更能让你深入理解苹果底层的运行机制,为学习Swift打下坚实的基础。

本指南将带你从Objective-C的基础语法开始,逐步深入到其特有的面向对象特性和高级运行时机制。

第一部分:基础篇

1.1 Objective-C初识

Objective-C是C语言的超集,它为C语言添加了Smalltalk式的面向对象特性。

  • 历史背景与特点: Objective-C起源于上世纪80年代,后来被NeXT公司采用,并随着苹果收购NeXT而成为macOS和iOS开发的官方语言。它的主要特点是动态性强、消息传递机制和对C语言的兼容。
  • 消息传递机制: Objective-C的核心是消息传递。当一个对象调用方法时,实际上是向该对象发送一条消息。运行时会根据消息选择合适的方法执行,这赋予了Objective-C强大的动态能力。
  • 类与对象: 在Objective-C中,一切皆对象。类是对象的蓝图,对象是类的实例。

1.2 基本语法与数据类型

Objective-C的语法混合了C语言和Smalltalk的风格。

  • #import@interface, @implementation:
    • #import: 类似于C的#include,但能有效避免重复导入。
    • @interface: 声明类的接口,包括属性和方法。
    • @implementation: 实现类中声明的方法。
  • 基本数据类型:
    • int, float, double, char: C语言的基本类型。
    • BOOL: Objective-C的布尔类型,通常定义为signed charYES为1,NO为0。
    • id: 通用对象类型,可以指向任何Objective-C对象,具有动态性。
    • nil: 指向Objective-C对象的空指针。
    • NULL: 指向C类型数据的空指针。
    • NSNumber: 将基本数据类型封装成对象,以便放入集合中。
  • 字符串:
    • NSString: 不可变字符串对象。例如:NSString *str = @"Hello";
    • NSMutableString: 可变字符串对象。
  • 集合类型:
    • NSArray: 不可变数组,有序集合。
    • NSMutableArray: 可变数组。
    • NSDictionary: 不可变字典(键值对)。
    • NSMutableDictionary: 可变字典。
    • NSSet: 不可变集合(无序不重复)。
    • NSMutableSet: 可变集合。

1.3 面向对象编程基础

  • @interface@implementation详解:
    “`objective-c
    // MyClass.h (接口文件)
    @interface MyClass : NSObject // 继承自NSObject
    {
    // 实例变量 (通常不直接访问,通过属性访问)
    // int _myValue;
    }
    // 属性声明
    @property (nonatomic, strong) NSString *name;

    // 方法声明
    – (void)doSomething; // 实例方法
    + (void)classMethod; // 类方法
    – (instancetype)initWithName:(NSString *)name; // 带参数的初始化方法

    @end

    // MyClass.m (实现文件)
    @implementation MyClass

    // 自动合成为 _name 和 setName: getName
    @synthesize name = _name; // 可省略,默认行为

    • (instancetype)init {
      self = [super init];
      if (self) {
      _name = @”DefaultName”; // 初始化实例变量
      }
      return self;
      }

    • (instancetype)initWithName:(NSString *)name {
      self = [super init];
      if (self) {
      _name = name;
      }
      return self;
      }

    • (void)doSomething {
      NSLog(@”Doing something with name: %@”, self.name);
      }

    • (void)classMethod {
      NSLog(@”This is a class method.”);
      }

    @end
    ``
    - **属性(
    @property)与实例变量(ivar)**:
    -
    @property: 声明一个属性,编译器会自动生成setter和getter方法以及一个对应的实例变量(前缀为_)。
    -
    ivar(Instance Variable): 类的成员变量,存储对象的状态。
    - 属性修饰符:
    - 内存管理:
    strong,weak,copy,assign(针对基本类型)
    - 原子性:
    atomic(默认),nonatomic(非原子性,效率更高)
    - 读写:
    readwrite(默认),readonly- **方法(实例方法,+类方法)**:
    - 实例方法:以
    开头,需要通过类的实例调用。
    - 类方法:以
    +开头,通过类名直接调用,不能访问实例变量。
    - **初始化方法(
    init,initWith…)**: 对象创建后调用的第一个方法,用于初始化实例变量。
    -
    init是默认初始化方法。
    -
    initWith…是带参数的初始化方法。
    - **继承**: Objective-C支持单继承,一个类只能继承自一个父类。所有Objective-C对象最终都继承自
    NSObject`。

1.4 内存管理 (MRC vs ARC)

Objective-C早期采用MRC,现在主流是ARC。

  • 引用计数(Retain Count)原理: 每个对象都有一个引用计数器,当对象被引用时计数加1(retain),引用释放时计数减1(release)。当计数为0时,对象被销毁(dealloc)。
  • MRC (Manual Reference Counting) 简述: 开发者手动管理对象的引用计数,通过retain, release, autorelease等方法来控制对象的生命周期。容易出错,导致内存泄漏或野指针。
  • ARC (Automatic Reference Counting) 详解: 编译器在编译时自动插入内存管理代码(retain, release等),代替开发者手动管理。大大降低了内存管理出错的可能性。ARC下,strong引用会增加引用计数,weak引用不会增加,用于解决循环引用问题。

第二部分:进阶篇

2.1 Category (分类)

Category允许在不修改原有类代码的情况下,为类添加新的方法。

  • 作用与使用场景:
    • 扩展现有类的功能,例如为NSString添加一个验证邮箱格式的方法。
    • 拆分大型类的实现,使代码更模块化。
  • 原理与限制:
    • 在运行时,Category的方法会被加载到主类的方法列表中。
    • Category可以添加方法,但不能添加实例变量(ivar)。
    • Category中的方法会覆盖主类中同名的方法(慎用)。

2.2 Extension (类扩展/匿名分类)

Extension是Category的一种特殊形式,通常在类的主@implementation块的@interface文件中声明。

  • 与Category的区别: Extension可以在编译时为类添加私有属性和私有方法。
  • 使用场景: 声明私有属性、私有方法,或实现协议,通常用于将类的内部实现细节隐藏起来。

2.3 Protocol (协议)

Protocol定义了一组方法,任何类都可以采纳(conform to)这些协议并实现其中的方法。

  • 作用与Delegate模式:
    • 定义接口规范,实现多态性。
    • Delegate (委托)模式的核心:一个对象(delegate)代表另一个对象(delegator)执行特定任务或响应特定事件。
  • @required, @optional:
    • @required: 采纳协议的类必须实现的方法。
    • @optional: 采纳协议的类可以选择性实现的方法。

2.4 Block (代码块)

Block是Objective-C中的闭包,可以捕获其定义时的上下文变量。

  • 定义与使用:
    “`objective-c
    // 定义一个Block类型
    typedef void (^MyBlock)(int);

    // 声明并使用Block
    MyBlock block = ^(int num) {
    NSLog(@”Block executed with number: %d”, num);
    };
    block(10);
    - **循环引用问题 (`__weak`)**: 当Block和它捕获的对象相互持有引用时,会导致循环引用(Retain Cycle),造成内存泄漏。解决方法是使用`__weak`或`__unsafe_unretained`修饰捕获的对象。objective-c
    __weak typeof(self) weakSelf = self;
    self.myBlock = ^{
    [weakSelf doSomethingElse]; // 使用weakSelf
    };
    “`

2.5 Key-Value Coding (KVC)

KVC是一种间接访问对象属性的机制,通过字符串来识别属性。

  • 基本概念与使用: 允许通过属性名称的字符串来获取或设置对象属性的值。
    • [object valueForKey:@"propertyName"]: 获取属性值。
    • [object setValue:value forKey:@"propertyName"]: 设置属性值。
  • KVC路径: 支持通过“点语法”访问嵌套属性。
    • [object valueForKeyPath:@"relationship.propertyName"]

2.6 Key-Value Observing (KVO)

KVO是一种观察者模式的实现,允许对象监听其他对象属性的变化。

  • 注册与移除观察者:
    • [object addObserver:observer forKeyPath:@"propertyName" options:NSKeyValueObservingOptionNew context:nil];
    • [object removeObserver:observer forKeyPath:@"propertyName" context:nil];
  • 实现原理: KVO底层依赖于Objective-C的Runtime机制。当一个对象首次被观察时,系统会动态创建一个其类的子类,并重写被观察属性的setter方法,在其中插入通知逻辑。

2.7 Runtime (运行时)

Objective-C的运行时系统是其动态特性的基石,它允许我们在程序运行时检查、修改类和对象的行为。

  • 概念与动态性: Runtime是一个底层的C语言API,提供了动态创建类、添加方法、交换方法实现等能力。
  • 消息发送机制 (objc_msgSend): Objective-C方法调用在编译时并不确定具体的函数地址,而是在运行时通过objc_msgSend函数发送消息来查找并执行对应的方法。
  • 方法交换 (Method Swizzling) 简介: 利用Runtime在运行时替换类的方法实现,常用于AOP (面向切面编程) 和调试。

2.8 Bridge (桥接)

Objective-C和Swift的混编是苹果生态系统中的一个重要特性,允许两种语言的项目相互调用。

  • Objective-C与Swift的混编:
    • Swift调用Objective-C: 需要一个Objective-C Bridging Header文件。
    • Objective-C调用Swift: Swift类需要继承自NSObject,并使用@objc关键字暴露给Objective-C。
  • @objc, NS_ASSUME_NONNULL_BEGIN, NS_ASSUME_NONNULL_END:
    • @objc: 标记Swift类、方法或属性,使其能在Objective-C中访问。
    • NS_ASSUME_NONNULL_BEGIN, NS_ASSUME_NONNULL_END: 用于在Objective-C头文件中声明一个区域,在该区域内所有不显式声明为nullable的指针类型都被视为nonnull,有助于提高与Swift的互操作性。

结语

尽管Swift已成为主流,但Objective-C作为苹果平台开发的奠基石,其深厚的历史和独特的运行时特性仍然值得我们学习。掌握Objective-C不仅能让你更好地理解和维护现有项目,更能加深你对整个苹果开发生态系统的理解。希望本指南能为你打开Objective-C世界的大门,助你成为一名更全面的苹果开发者。继续学习Swift,你将会发现Objective-C的知识将为你提供独特的视角。

滚动至顶部