当前位置: 首页 > news >正文

Objective-C面向对象编程:类、对象、方法详解(保姆级教程)

目录

一、核心概念

二、类的定义(分.h和.m文件)

1. 头文件(.h)—— 公开声明

2. 实现文件(.m)—— 具体实现

3.  属性特性解析

原子性

所有权语义(ARC环境下)

读写控制

三、对象创建与内存管理

1. 创建对象的两种方式

2. 关键步骤解析

3. instancetype

四、方法调用(消息传递机制)

1. 基本语法

2. 关键概念

五、self与super关键字

六、动手实践:完整工作流

1. 创建Person对象并调用方法

2. 项目结构

七、关键概念对比表

八、常见问题解答

相关推荐


一、核心概念

  1. :对象的蓝图(定义属性和方法)
  2. 对象:类的实例(内存中的具体实体)
  3. 方法:对象的行为(实例方法 - / 类方法 +

二、类的定义(分.h和.m文件)

1. 头文件(.h)—— 公开声明

#import <Foundation/Foundation.h>@interface SccUser : NSObject  // 继承NSObject// 属性声明(编译器自动生成getter/setter)
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;// 方法声明
- (void)sayHello;            // 实例方法
+ (void)run;                 // 类方法@end

编译器的自动合成:

  • 自动生成实例变量(默认带下划线前缀:_name_age)
  • 自动生成getter和setter方法
  • 根据属性特性自动处理内存管理

2. 实现文件(.m)—— 具体实现

#import "SccUser.h"@implementation SccUser- (void)sayHello {NSLog(@"say:HelloKitty");
}+ (void)run {NSLog(@"奔跑吧,类方法。");
}@end

3.  属性特性解析

属性特性分为三类:原子性、所有权语义和读写控制。

原子性
  • atomic(默认):线程安全的getter/setter,但性能稍低
  • nonatomic:非线程安全,但性能更好(推荐在单线程环境使用)
所有权语义(ARC环境下)
特性适用类型描述
strong对象类型默认值,保持强引用,引用计数+1
weak对象类型弱引用,不增加引用计数,对象释放后自动置nil(解决循环引用)
assign基本数据类型简单赋值,不进行引用计数管理(用于int, float, BOOL等)
copy对象类型(特别是NSString/NSArray等)创建对象的副本(保护不可变对象不被外部修改)
unsafe_unretained对象类型类似assign,但对象释放后不自动置nil(不安全,尽量用weak代替)
读写控制
  • readwrite(默认):生成getter和setter
  • readonly:只生成getter

三、对象创建与内存管理

1. 创建对象的两种方式

// 标准方式(推荐)
SccUser *user1 = [[SccUser alloc] init]; // 简化方式(等效于alloc+init)
SccUser *user2 = [SccUser new]; 

2. 关键步骤解析

方法作用
alloc分配内存(从堆区申请空间)
init初始化对象(设置默认值)

✅ 最佳实践:自定义初始化方法示例

// SccUser.h中添加
- (instancetype)initWithName:(NSString *)name;// SccUser.m中实现
- (instancetype)initWithName:(NSString *)name {self = [super init];if (self) {_name = name;  // 直接访问底层实例变量}return self;
}

3. instancetype

instancetype 是 Objective-C 引入的编译时类型检查关键字,用于表示:

"这个方法返回的实例类型,就是当前类的类型"

与 id 的对比(核心区别)

特性instancetypeid(通用对象指针)
类型安全性✅ 编译器会检查类型一致性❌ 绕过类型检查
代码智能提示✅ Xcode 提供精确的代码补全❌ 只能提示通用方法
继承场景行为✅ 子类继承时自动匹配实际类型❌ 永远返回 id
编译时优化✅ 编译器可进行静态分析❌ 无优化

四、方法调用(消息传递机制)

1. 基本语法

SccUser *user = [SccUser new];
// 无参数方法
[user sayHello];// 类方法
[SccUser run];// 带参数方法(冒号是语法关键)
[user setName:@"ShuaiciMain"];  // 等效于user.name = @"ShuaiciMain";// 多参数方法
[user userInfo:@"DaShuaiCi" is:18];

2. 关键概念

  • 选择器(SEL)@selector(sayHello) 表示方法签名
  • 消息传递[receiver message] 被编译为objc_msgSend(receiver, selector)

五、self与super关键字

关键字作用示例
self当前对象(类似Java/C++的thisself.name = @"Bob";
super调用父类实现[super init];

⚠️ 易错点:在init方法中必须用_name访问属性,避免触发未初始化的KVO


六、动手实践:完整工作流

1. 创建Person对象并调用方法

#import <Foundation/Foundation.h>
#import "SccUser.h"int main(int argc, const char * argv[]) {@autoreleasepool {// 1. 创建对象SccUser *alice = [[SccUser alloc] init];// 2. 设置属性(点语法本质是调用setter)alice.name = @"ShuaiciMain";// 3. 调用实例方法[alice sayHello];[alice userInfo:@"DaShuaiCi" is:18];// 4. 调用类方法[SccUser run];// 5. 使用自定义初始化SccUser *shuaici = [[SccUser alloc] initWithName:@"DaShuaiCi"];NSLog(@"自定义初始化:%@",shuaici.name);}return 0;
}

2. 项目结构

YourProject/
├── Person.h   // 头文件(声明)
├── Person.m   // 实现文件
└── main.m     // 程序入口

七、关键概念对比表

特性实例方法类方法
语法符号-(减号)+(加号)
调用对象类的实例类本身(如[Person ...]
内存归属对象内存空间类元数据空间
访问权限可访问实例变量不可访问实例变量
典型用途对象的具体操作工厂方法/工具类方法

八、常见问题解答

Q1:为什么属性用copy修饰字符串?

防止NSMutableString被意外修改(copy会创建不可变副本)

Q2:allocinit能分开调用吗?

可以但不推荐(可能产生未初始化对象):

Person *p = [Person alloc];  // 只有内存分配
p = [p init];                // 完成初始化

Q3:方法命名规范?

苹果官方要求:

  • 参数名嵌入方法名(sendData:toAddress:withTimeout:
  • 驼峰命名法(首个单词小写)

Q4:如何理解消息传递?

Objective-C运行时动态绑定过程:

  1. 通过isa指针查找对象类
  2. 在类的方法列表中查找SEL
  3. 若未找到则向父类传递消息
  4. 最终未处理则触发unrecognized selector异常

相关推荐

为何要学习Objective-C?从环境搭建开始-CSDN博客文章浏览阅读514次,点赞10次,收藏10次。在Objective-C开发中,你会频繁遇到以"NS"开头的类名和函数名,比如NSLog、NSString、NSArray等。这个"NS"前缀其实有着重要的历史渊源和技术含义。 https://shuaici.blog.csdn.net/article/details/148535298C语言基础精讲-CSDN博客文章浏览阅读10w+次,点赞413次,收藏2.1k次。C语言是当代人学习及生活中的必备基础知识,应用十分广泛,下面为大家带来C语言基础知识梳理总结,C语言零基础入门绝对不是天方夜谭!_c语言基础知识 https://shuaici.blog.csdn.net/article/details/60570837

http://www.lqws.cn/news/523945.html

相关文章:

  • 自动驾驶数据特征提取实战:用Python打开智能驾驶的新视角
  • 深入理解残差网络(ResNet):原理与PyTorch实现
  • Mysql数据库操作大全万字详解
  • 【Redis】Redis的下载安装和配置
  • 检查StringBuilder是否包含字符串
  • ARM内核之CMSIS
  • 【机器学习】非参数贝叶斯回归方法 GPR
  • ipfs在windows下载和安装
  • JSON框架转化isSuccess()为sucess字段
  • C++(智能指针)
  • Liunx操作系统笔记2
  • linux-修改文件命令(补充)
  • IT运维效率提升: 当IT监控遇上3D可视化
  • 三步实现B站缓存视频转MP4格式
  • 记一次AWS 中RDS优化费用使用的案例
  • Postman鉴权动态传参?对比脚本变量vs环境变量!
  • 理论加案例,一文读懂数据分析中的分类建模
  • 通过pyqt5学习MVC
  • 代理型 AI 重塑营销格局:国产 R²AIN SUITE 如何破解数据与技术瓶颈,实现 AI 赋能全链路提效
  • VScode常用快捷键【个人总结】
  • 2024年AEI SCI1区TOP,强化学习人工兔优化算法RLTARO+山地森林地形无人机编队路径规划,深度解析+性能实测
  • Dify、n8n、Coze、FastGPT 和 Ragflow 对比分析:如何选择最适合你的智能体平台?
  • Wpf的Binding
  • 数据库1.0
  • Python 爬虫入门:从数据爬取到转存 MySQL 数据库
  • 【Ansible】Ansible入门
  • Git常用操作详解
  • Python核心可视化库:Matplotlib与Seaborn深度解析
  • React 第六十四节Router中HashRouter的使用详细介绍及案例分析
  • 重置 MySQL root 密码