NSObject:类与协议

转载 2013年12月04日 14:04:20
感谢翻译小组成员dada9088热心翻译。本篇文章是我们每周推荐优秀国外的技术类文章的其中一篇。本周另外还有《为M7处理器做开发》、《了解框架》、《iOS面试问题》三篇文章。会在近日出炉,欢迎关注。如果您有不错的原创或译文,欢迎提交给我们,更欢迎其他朋友加入我们的翻译小组(联系qq:2408167315)。
 
 
读者 Tomas Bouda asks问:NSObject协议到底是什么?
Cocoa有两个NSObject,一个是类,一个是协议。为什么有两个?用来做什么?我将通过这篇文章来解答这些问题。
 
命名空间
首先,我们看看这两个有着相同命名的部分是怎么共处的。在Objective-c中,类和协议分别存在于不同的命名空间。类和协议拥有相同的命名,但是跟语言层级无关。这就是NSObject。
 
如果你光看语句,这里没有什么不同。 类命名可以用在目标的消息发送,在@interface的声明部分,作为类型名。协议也可以用在同样的地方,但是用不同的方式。所以再没有比相同名字更容易让人混淆的了。
 
根类
NSObject类是根类,在所有类的最高层级,所以没有更高层的类了。Objective-c可以有多个根类,不像Java只有一个。
 
Java只有一个根类:java.lang.Object,其他所有的类都直接或间接的继承于它。所以Java代码可以依据任何对象来实现java.lang.Object的基本方法。
 
Cocoa有多个根类。除了NSObject还有NSProxy和其它等级的根类。这只是部分原因,NSObject协议定义了一套基础方法,所有的根类都可以去实现。这样,编码时就容易找到这些方法了。
 
NSObject类符合NSObject协议,这就是说,NSObject类实现了下面这些基础方法:
  1. @interface NSObject <NSObject> 
 
NSProxy同样符合NSObject协议:
  1. @interface NSProxy <NSObject> 
NSObject协议包含了hash,isEqual:,description等方法。事实上,NSProxy遵循NSObject协议意味着你可以依靠实现NSProxy来实现NSObject方法。
 
顺便说说Proxy
既然我们说到这里,为什么这里有一个NSProxy作为根类?
 
很多情况下去拥有一个类而不实现太多的方法会很有用。作为命名的建议,proxy对象就是这样的情况。NSObject类实现了比NSObject协议更多的东西,比如键值编码,你不需要它。
 
当建立proxy对象,通常是为了留给大多数未实现的方法,所以他们就可以使用一个forwardInvocation:方法来转发。把NSObject作为子类则可能会引入更多包,那样将会冲突。而NSProxy可以避免,因为提供了一个简单的超类,所以不会有多余的东西在里面。
 
协议
实际上,NSObject协议是一个很好的根协议,并不全表现在Objective-c编程上,因为我们并不经常使用其他的根类。然而,它在我们创建自己协议的时候很使用。比如,你的协议可能是这样写的:
  1.  @protocol MyProtocol 
  2. - (void)foo; 
  3.  
  4. @end 
 
同时,你定义一个类指针:
  1. id<MyProtocol> obj; 
你可以这样调用foo:
  1. [obj foo]; 
当然,你不能这样使用description:
  1. [obj description]; // no such method in the protocol 
同样,你也不能这样检测相等:
  1. [obj isEqual: obj2]; // no such method in the protocol 
总的来说,你不能要求它来做一般对象做的事情。有时这没关系,但是有时又需要实现这些。这就是为什么要引进NSObject协议。协议可以继承于协议。你可以使MyProtocol继承于NSObject协议,像这样:
  1. @protocol MyProtocol <NSObject> 
  2. - (void)foo; 
  3. @end 
这就是说不仅仅对象遵循MyProtocol协议并响应-foo,而且响应所有在NSObject协议中所有类似的消息。因此你应用中所有的对象都继承于NSObject类并且遵循NSObject协议,这样在实现MyProtocol时不需要更多的条件,同时允许你在实例中使用这些相同的方法实例。
 
总结
frameworks框架中有两个不同的NSObject确实比较奇怪,但是当你理解了它会非常有用。一个NSObject协议允许多个根类拥有相同的基础方法。同时,对象可以很容易去声明一个包含相同基础功能协议。NSObject类遵循了NSObject协议,把所有的东西融合到一起。

NSObject class和NSObject protocol的关系(抽象基类与协议)

1、接口的实现 对于接口这一概念的支持,不同语言的实现形式不同。Java中,由于不支持多重继承,因此提供了一个Interface关键词。而在C++中,通常是通过定义抽象基类的方式来实现接口定义的...
  • Net_Joe
  • Net_Joe
  • 2015年02月24日 10:16
  • 1259

iOS Copy 和 MutableCopy的区别 深浅拷贝的区别

原创的链接在这里: 原创的地址请点击这里哦 概述 对于系统的非容器类对象,对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)。如果是对可变对象复...
  • fanjunxi1990
  • fanjunxi1990
  • 2013年11月20日 17:27
  • 5342

iOS SDK详解之NSCoding协议

原创blog,转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=contents 欢迎关注我的iOS SDK详解专栏 http://blog.csd...
  • Hello_Hwc
  • Hello_Hwc
  • 2015年08月14日 20:08
  • 3873

NSObject:类与协议

感谢翻译小组成员dada9088热心翻译。本篇文章是我们每周推荐优秀国外的技术类文章的其中一篇。本周另外还有《为M7处理器做开发》、《了解框架》、《iOS面试问题》三篇文章。会在近日出炉,欢迎关注。如...
  • wangkai598
  • wangkai598
  • 2013年12月04日 10:33
  • 691

NSObject class和NSObject protocol的关系(抽象基类与协议)

1、接口的实现 对于接口这一概念的支持,不同语言的实现形式不同。Java中,由于不支持多重继承,因此提供了一个Interface关键词。而在C++中,通常是通过定义抽象基类的方式来实现接口定义的...
  • Net_Joe
  • Net_Joe
  • 2015年02月24日 10:16
  • 1259

objective-C 编程全解-第08章 类NSObject和运行时系统 中 上

第08章 类NSObject和运行时系统 中 上 8.2 消息发送机制 8.2.1 选择器和SEL类型     程序中的方法名(选择器)在编译后会被一个内部标识符所替代,这个内部...
  • u014222687
  • u014222687
  • 2016年06月07日 15:26
  • 374

在NSObject子类中获取当前屏幕显示的ViewController

在NSObject子类中获取当前屏幕显示的ViewController 本篇文章主要介绍了"在NSObject子类中获取当前屏幕显示的ViewController",主要涉及...
  • wakice
  • wakice
  • 2017年03月27日 15:03
  • 196

Objective-C(九、Foundation框架和NSObject类)——iOS开发基础

Foundation框架简介,NSObject类简介,根类的作用,常用方法说明等等
  • Zsk_Zane
  • Zsk_Zane
  • 2015年07月03日 14:51
  • 1077

继承 多态 封装 NSObject类 super关键字 里氏替换 原则 SEL数据 Class

OC基础day05继承的简单使用 代码中的继承是什么意思? 继承是一个创建类的方式,当想要创建一个B类,但是不想写B中的成员,发现A中有自己想要的成员,这个时候就可以用继承关系 把A类中的所有成员...
  • lidian6864677
  • lidian6864677
  • 2016年08月20日 01:41
  • 233

在NSObject类中,和继承它的类中,弹出UIAlertcontroller和push、present到其它界面

在NSObject类中,和继承它的类中,弹出UIAlertcontroller和push、present到其它界面 笔者平时不喜欢讲废话,但是在这里还是要说下,这个功能,我实现的...
  • u010850094
  • u010850094
  • 2016年07月25日 11:01
  • 2085
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:NSObject:类与协议
举报原因:
原因补充:

(最多只允许输入30个字)