1.协议(protocol)和委托

1.1 规范、协议与接口

OC中协议的作用就相当于其他语言中接口的作用。协议定义的是多个类共同的公共行为规范,协议通常定义一组公用方法,但不提供实现。

1.2 定义

正式协议使用@protocol关键字来定义,语法如下:

@protocol 协议名<父协议1,父协议2>
{
//方法定义
}

一个协议可以有多个直接父协议,但协议只能继承协议不能继承类。协议中定义的方法只有方法签名,没有方法实现;协议中定义的方法既可以是类方法,也可以是实例方法。

1.3 实现协议

在类定义的接口部分可指定该类继承的父类和实现的协议

@interface 类名:父类 <协议1,协议2...>

@optional @required

1.4 协议和委托

2.使用@try处理异常

2.1 使用@try...@catch...@finally捕捉异常

OC提供了@try@catch@finally来捕捉异常。

@try
{
//业务实现代码
}
@catch(异常1 ex)
{
//异常处理
}
@catch(异常2 ex)
{
//异常处理
}
..
@finally
{
}

所有异常对象都包含下面几个常用方法:

  • name 返回该异常详细的名称
  • reason 返回该异常的原因
  • userInfo 返回引发该异常的用户附加信息,返回一个NSDictionary对象

在程序中自行抛出异常,使用@throw语句 @throw ExceptionInstance;

3.反射

OC提供了3中方式与运行环境交互

  1. 直接通过OC的源代码
  2. 通过NSObject类中定义的方法进行动态变成
  3. 直接调用运行时函数进行动态编程

3.1 获得Class

每个类都有一个对应的Class,OC获得Class的三种方式:

  1. 使用Class NSClassFromString(NSString* aClassName)函数来获取Class,字符串参数是某个类的雷鸣
  2. 调用某个类的class方法来获取该类对应的Class。 [FKItem class]
  3. 调用对象的class方法

3.2 检查继承关系

  1. -isKindOfClass ,传入一个Class参数,判断该对象是否该该类及其子类的实例
  2. -isMemberOfClass ,传入CLass参数,判断该对象是否为该类及其子类的实例
  3. -conformsToProtocol ,传入一个Protocol参数,判断该对象是否为该类及其子类的实例

获取Protocol参数的方法

  1. OC提供@protocol指令
  2. 调用 Protocol* NSProtocolFromString(NSStirng* namestr)

3.3 动态调用方法

判断某个对象是否可调用方法,可通过NSObject的如下方法进行判断:

respondsToSelector: 传入一个SEL参数-OC 把方法成为选择器,

OC中动态获取SEL对象的方法

  1. 使用@selector指令来获取当前类中制定的方法。该指令需要用完整的方法签名关键字作为参数
  2. 使用SEL NSSelectorFromString(NSString* aSelectorName)函数根据方法签名关键字的字符串来获取对应方法。

动态调用对象的普通方法,两种方式实现:

  1. 用过NSObject的performSelector:方法实现,第一个参数传入SEL对象,如果调用方法需要参数,可以通过withObject:标签传入参数。
  2. 使用 objc_msgSend(receiver,selector,...),第一个参数是方法调用者,第二个参数是调用的方法,接下来的参数作为调用方法的参数。要导入 <objc/message.h>头文件

-(IMP)methodForSelector:(SEL)aSelector: 传入SEL参数,返回对应的IMP对象。

IMP相当于一个指向函数的指针变量,也就是代表了函数的入口,可以通过IMP来调用该函数.

返回值类型 (* 指针变量名)(id,SEL,...);


#import <Foundation/Foundation.h>
#import <objc/message.h> @interface FKCar:NSObject
@end @implementation FKCar
-(void) move:(NSNumber*) count
{
int num =[count intValue];
for (int i = 0; i < num; ++i)
{
NSLog(@"%@",[NSString stringWithFormat:@"汽车正在路上走~~%d",i]);
}
}
-(double) addSpeed:(double)factor
{
[self performSelector:@selector(move:)
withObject:[NSNumber numberWithInt:2]];
[self performSelector:NSSelectorFromString(@"move:")
withObject:[NSNumber numberWithInt:2]]; objc_msgSend(self,@selector(move:)
,[NSNumber numberWithInt:3]);
objc_msgSend(self,NSSelectorFromString(@"move:"),[NSNumber numberWithInt:3]); NSLog(@"正在加速。。。%g",factor);
return 100 * factor;
}
@end int main(int argc, char const *argv[])
{
@autoreleasepool{
//获取FKCar类
Class clazz = NSClassFromString(@"FKCar");
//动态加载FKCar对象
id car = [[clazz alloc] init];
//使用performSelector:方法来动态调用方法
[car performSelector:@selector(addSpeed:)
withObject:[NSNumber numberWithDouble:3.4]];
//使用objc_msgSend() 函数动态调用方法
objc_msgSend(car,@selector(addSpeed:),3.4);
//定义函数指针变量
double (*addSpeed)(id,SEL,double);
//获取car对象的addSpeed:方法,并将该方法赋值给addSpeed函数指针变量
addSpeed = (double(*)(id,SEL,double))[car
methodForSelector:NSSelectorFromString(@"addSpeed:")];
//通过addSpeed函数指针变量来调用car对象的方法
double speed = addSpeed(car ,@selector(addSpeed:),2.4);
//输出调用方法的返回值
NSLog(@"加速后的速度为:%g",speed);
}
}

4.手动内存管理

OC可用的内存回收机制有三种:

  1. 手动引用计数和自动释放池
  2. 自动引用计数(ARC Automatic Reference Counting)
  3. 自动垃圾回收(iOS 不支持)

4.1 对象的引用计数

OC采用了一种引用计数(Reference Counting)的计数来跟踪对象的状态。

在手动计数中,改变对象的引用计数的方式如下:

  1. 当程序调用方法名以alloc、new、copy、mutableCopy开头的方法来创建对象时,该对象的引用计数加1
  2. 程序调用对象的retain方法时,该对象的引用计数加1
  3. 程序调用对象的release方法时,该对象的引用计数减1

NSObject提供了有关引用计数的如下方法:

  1. -retian: 将对象的引用计数器加1
  2. -release: 将该对象的引用计数器减1
  3. -autorelease: 不改变对象的引用计数器的值,只是将对象添加到自动释放池
  4. -retainCount: 返回该对象的引用计数的值

4.2 对象所属权

手动释放内存的基本思路应该遵循:谁(对象、函数)把对象的引用计数加1,就要在销毁前把该对象的引用计数减1.

Objective-C面向对象(四)的更多相关文章

  1. iOS开发核心语言Objective C —— 面向对象思维、setter和getter方法及点语法

    本分享是面向有意向从事iOS开发的伙伴们.或者已经从事了iOS的开发人员.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基础,建议您先翻阅我之前分享的iOS ...

  2. Python之面向对象四

    面向对象进阶 一.关于面向对象的两个内置函数 isinstance   判断类与对象的关系    isinstance(obj,cls)检查obj是否是类 cls 的对象,返回值是bool值 issu ...

  3. 【iOS 开发】Objective - C 面向对象 - 方法 | 成员变量 | 隐藏封装 | KVC | KVO | 初始化 | 多态

    一. Objective-C 方法详解 1. 方法属性 (1) OC 方法传参机制 Object-C 方法传参机制 : OC 中得参数传递都是值传递, 传入参数的是参数的副本; -- 基本类型 (值传 ...

  4. 【IOS 开发】Objective - C 面向对象高级特性 - 包装类 | 类处理 | 类别 | 扩展 | 协议 | 委托 | 异常处理 | 反射

    一. Objective-C 对象简单处理 1. 包装类 (1) 包装类简介 NSValue 和 NSNumber : -- 通用包装类 NSValue : NSValue 包装单个 short, i ...

  5. python学习之面向对象(四)

    6.9 反射 反射是非常重要的内置函数之一. 反射是通过字符串去操作对象相关的属性,这里的对象包括:实列,类,当前模块,其他模块. 主要的四个函数: 查看: hasattr(对象,待查内容的字符串形式 ...

  6. 深入java面向对象四:Java 内部类种类及使用解析(转)

    内部类Inner Class 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分. Java中的内部类共分为四种: 静态 ...

  7. 疯狂java学习笔记之面向对象(四) - this关键字

    Java中this关键字主要有以下两个方法: 1.this引用 - 可用于任何非static修饰的方法和构造器中,当this用于方法中时,它代表调用该方法的实例/对象;当this用于构造器中时,它代表 ...

  8. Python 面向对象(四) 反射及其魔术方法

    反射 reflection 也有人称之为自省 作用: 运行时获取.添加对象的类型定义信息,包括类 内建方法: getattr(object, name[, default])   返回object对象 ...

  9. Java学习笔记11(面向对象四:多态)

    多态: 举例:描述一个事物的多种形态,如Student类继承了Person类,一个Student对象既是Student,又是Person 多态体现为:父类引用变量可以指向子类对象 多态的前提:必须有子 ...

随机推荐

  1. Chrome调试(debugger)总是进入paused in debugger状态

    在通过Chrome浏览器进行web前端开发时,我们会经常用到Chrome自带的debugger工具,但是经常按完快捷键(F12)后,页面会进入 paused in debugger状态,需要点击右上角 ...

  2. ASP.NET的SEO--- Global.asax和HttpModule中的RewritePath()方法

    本系列目录 因为在网上搜到了很多这方面的文章,而且UrlRewrite中SEO中的重要性也在逐步下降,所以这一节我就写得简单一些.以下是几个重点: 1.UrlRewrite,顾名思义,只是针对URL进 ...

  3. WP8_当滚动到滚动条的70%时,自动加载数据效果实现

    Touch.FrameReported += Touch_FrameReported;   void Touch_FrameReported(object sender, TouchFrameEven ...

  4. Linux设备模型 学习总结

    看LDD3中设备模型一章,觉得思维有些混乱.这里从整体的角度来理理思路.本文从四个方面来总结一些内容: 1.底层数据结构:kobject,kset.2.linux设备模型层次关系:bus_type,d ...

  5. Linux:ssh远程执行命令并自动退出

    ssh命令格式: [root@localhost ~]# ssh --helpusage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c ...

  6. c++ 实现百度自动搜索

    void CAttendanceRobotDlg::DocumentCompleteExplorer4(LPDISPATCH pDisp, VARIANT* URL) { // TODO: Add y ...

  7. Win7系统下VS2008安装SP1补丁解决JQuery无智能提示的问题

    jQuery在vs2008中的智能提示 1  安装VS2008SP1补丁 要确保您的vs2008已经打了sp1补丁,在vs2008的帮助里的关于,要是安装了sp1,会出现“版本 3.5 sp1”,没安 ...

  8. sqlserver 保留小数方法

    1. 使用 Round() 函数,如 Round(@num,2)  参数 2 表示 保留两位有效数字. 2. 更好的方法是使用 Convert(decimal(18,2),@num) 实现转换,dec ...

  9. Mysql导入导出 改密命令总结(笔记三)

    一.从数据库导出数据 注意这些语句的执行是在在没进入mysql命令行之前,在mysql命令行不行 C:\Windows\system32>导出命令 而不是 Mysql>导出命令 1.导出整 ...

  10. php获取客户端浏览器以及操作系统信息的方法

    发布:sunday01   来源:net   阅读: 2   [大 中 小] 在较为智能的程序中,php可以获取客户端浏览器及操作系统信息,然后根据浏览器及系统类型,加载不同的页面,以提供更加个性化的 ...