iOS开发核心语言Objective C语言 —— 特有语法及设计模式

本文深入解析Objective-C中的Category分类、Extension扩展、Block闭包、Protocol协议及代理设计模式等核心特性,介绍它们的定义、作用及应用场景,并提供详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://blog.youkuaiyun.com/zc639143029/article/details/47685509

本分享是面向有意向从事iOS开发的伙伴及苹果产品的发烧友,亦或是已经从事了iOS的开发者,想进一步提升者。如果您对iOS开发有极高的兴趣,可以与我一起探讨iOS开发,一起学习,共同进步。如果您是零基础,建议您先翻阅我之前分享的iOS开发分分钟搞定C语言系列,然后在开始Objective C语言的学习,如果您遇到问题也可以与我探讨,另外将无偿分享自己整理出来的大概400G iOS学习视频及学习资料,都是干货哦!可以新浪微博私信➕关注极客James,期待与您的共同学习和探讨!!由于时间有限,每天在工作之余整理的学习分享,难免有不足之处,也希望各路大神指正!

made by :极客James 
这里写图片描述

一、category 分类

在C++中有强大的多重继承,而在oc中方法都是单继承的,为了模块化开发,便于团队开发,oc中有其他语言所没有的category(分类,类目,类别)和class Exetension(类扩展)等语法,可以在不修改原来类的基础上, 为这个类扩充一些方法.

Category的格式 
1.在.h文件中声明类别 
(1)新添加的方法必须写在 @interface 与 @end之间 
(2)ClassName 现有类的类名(要为哪个类扩展方法) + 
(3)CategoryName 待声明的类别名称 
(4)NewMethod 新添加的方法

@interface ClassName (CategoryName) NewMethod; 
//在类别中添加方法 
//不允许在类别中添加变量 
@end

注意: 
不允许在声明类别的时候定义变量

在.m文件中实现类别: 
(1)新方法的实现必须写在@ implementation与@end之间 
(2)ClassName 现有类的类名 
(3)CategoryName 待声明的类别名称 
(4)NewMethod 新添加的方法的实现

category使用注意: 
1. 分类只能增加方法, 不能增加成员变量 
2. 分类中写property只会生成方法声明 
3. 分类可以访问原来类中的成员变量 
4. 如果分类和原来类出现同名的方法, 优先调用分类中的方法, 原来类中的方法会被忽略

分类的编译的顺序 
方法调用顺序(从高到低) 分类 –>原来类 –>父类

分类应用场景:开发中经常使用的方法,可以抽出一个分类,团队开发中,多人共同开发,可以写多个分类,最后进行融合。

二、Exetention 匿名扩展

1.匿名扩展定义 
延展类别又称为扩展(Extendsion),Extension是Category的一个特例 
可以为某个类扩充一些私有的成员变量和方法写在.m文件中 
英文名是Class Extension

2.扩展书写格式 
在.m文件中

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@interface</span> 类名 ()</span>
{
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> _age;
}
- (<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span>)say;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@end</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

三、Block

1.Block简介 
Block是iOS中一种比较特殊的数据类型 
Block是苹果官方特别推荐使用的数据类型, 应用场景比较广泛。 
Block应用场景: 
动画 
多线程 
集合遍历 
网络请求回调

2.Block的作用 
用来保存某一段代码, 可以在恰当的时间再取出来调用 
功能有点类似于函数和方法。

3.Block的定义格式: 
返回值类型 (^block变量名)(形参列表) = ^(形参列表) { 
}; 
(1)无返回值,无形参 
void(^Myblock)() = ^{ 
NSLog(@”Hello”); 
}; 
(2)有返回值,有形参 
int(^MyBlock)(int,int) = ^(int a,int b){ 
return a +b; 
}; 
(3)无返回值,有形参 
void(^MyBlock)(int) = ^(int num){ 
for (int i = 0,i

三、Protocol 协议

1.protocol 基本概念 
Protocol翻译过来, 叫做”协议”

(1)在写java的时候都会有接口interface这个概念,接口就是一堆方法的声明没有实现,而在OC里面Interface是一个类的头文件的声明,并不是真正意义上的接口的意思,在OC中接口是由一个叫做协议的protocol来实现的 
protocol它可以声明一些必须实现的方法和选择实现 的方法。这个和java是完全不同的。

2.Protocol的作用: 
用来声明一些方法,也就说, 一个Protocol是由一系列的方法声明组成的。

3.protocol 语法格式 
(1)Protocol的定义 
@protocol 协议名称 
// 方法声明列表 
@end 
(2)类遵守协议 
一个类可以遵守1个或多个协议 
任何类只要遵守了Protocol,就相当于拥有了Protocol的所有方法声明.

4.protocol和继承区别 
继承之后默认就有实现, 而protocol只有声明没有实现 
相同类型的类可以使用继承, 但是不同类型的类只能使用protocol 
protocol可以用于存储方法的声明, 可以将多个类中共同的方法抽取出来, 以后让这些类遵守协议即可。

5.协议中的两个关键字 
有2个关键字可以控制方法是否要实现(默认是@required,在大多数情况下,用途在于程序员之间的交流) 
@required:这个方法必须要实现(若不实现,编译器会发出警告) 
@optional:这个方法不一定要实现

6.协议的局限性 
协议是用来声明一大堆的方法,不能声明成员变量,也不能写实现方法,而某个类遵守了这个协议就可以进行协议中声明的方法的实现,这样虽然能解决OC的单继承问题,但是有类型的限制,不能够更好的做到程序的扩展性,那么在协议的基础上通过什么能够更具扩展性呢?答案是—— 代理。

7.协议的注意事项 
(1)协议只能声明方法, 不能声明属性 
(2)父类遵守了某个协议, 那么子类也会自动遵守这个协议 
(3)在OC中一个类可以遵守1个或多个协议 
注意: OC中的类只能有一个父类, 也就是说OC只有单继承 
(4)OC中的协议又可以遵守其它协议, 只要一个协议遵守了其它协议, 那么这个协议中就会自动包含其它协议的声明。

8.协议的应用场景及注意点 
(1)做类型限定 
类型限定就是限定一个类必须遵守某个协议 
数据类型<协议名称> 变量名

<code class="hljs css has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-at_rule" style="box-sizing: border-box;">@<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">proterty(nonatomic</span> , strong)dog< DogRunning > *dog</span>;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

(2)类型限定的注意点 
1.类型限定是写在数据类型的右边的 
2.虽然在接受某一个对象的时候, 对这个对象进行了类型限定(限定它必须实现某个协议), 
3但是并不意味着这个对象就真正的实现了该方法. 所以每次在调用对象的协议方法时应该进行一次验证

<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>([<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.dag <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">respondsToSelect:</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@selector</span>(run)]){
    [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.dog run];
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

四、委托代理

1.什么是设计模式? 
在计算机编程语言中有32种设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样,在iOS中常用的实际模式为:代理方法,MVC模式,MVVC模式,单例模式等。

2.代理设计模式 
代理模式是iOS开发中非常重要的一种设计模式,在UI中用的最多,有以下两种情况: 
(1)当对象A发生了一些行为,想告知对象B(让对象B成为对象A的代理对象)对象B想监听对象A的一些行为(让对象B成为对象A的代理对象) 
(2)当对象A无法处理某些行为的时候,想让对象B帮忙处理(让对象B成为对象A的代理对象)

3.代理编写规范 
(1)一般代理属于谁,就写在谁的头文件中定义。 
(2)协议的名称一般以他得属性的那个类的类名开头,后面跟上Protocol或者Delegate。 
(3)协议中的方法名称一般以协议的名称Protocol之前的作为开头。

4.接受遵守协议的代理对象关键字 
id关键字接受遵守协议的代理

<code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">@property</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">nonatomic</span>,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">weak</span>)<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">id</span>< DogDelegate>dog;</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li></ul>

5.实现代理的步骤 
发出代理者: 
(1)声明一个类: 
@class 类名 
(2)定义代理协议 
(3)将代理作为属性,类型限定代理遵守协议 
(4)声明方法,方法里调用代理,调用代理实现的协议方法 
接受代理者 
(5)带入代理 
(6)遵守代理 
(7)实现协议中的方法 
发出的代理者 
(8)实现调用代理者的方法 
判断代理是否实现了协议中的方法 
如果代理实现了代理中的方法,就调用

<code class="hljs ruby has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">      <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> ([<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.delegate <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">respondsToSelector:</span><span class="hljs-variable" style="color: rgb(102, 0, 102); box-sizing: border-box;">@selector</span>(<span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">eat:</span>)]) {
        [<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>.delegate <span class="hljs-symbol" style="color: rgb(0, 102, 102); box-sizing: border-box;">eat:</span><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">self</span>];
        }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li></ul>

@class与#import的区别 
两个点: 
(1)作用上得区别: 
·#import会包含引用类的所有信息(内容),包括引用类的变量和方法 .@class仅仅告诉编译器有这么一个类,具体这个类有什么信息,完不知 
(2 )效率上得区别. 
如果有上百个头文件都#import了同一个文件,或者这些文件依次被#import,那么一旦最开始的文件有改动,后面引用到这个文件的所有类都需要重新编译一变,效率非常低

以上是本人对OC特有语法及代理设计模式的总结和分享。下篇将分享Objective C语言中的重要框架Foundation框架,敬请期待。另外需要iOS学习资料的伙伴们可以新浪微博私信➕关注极客James。 
这里写图片描述


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值