作为一个初学者,我一直很弄不明白NSCell的子类,比如,NSButtonCellNSImageCell及其对应的控件之间的关系。今天,在做一个TableView实现的时候,我终于开始有点悟了——好吧,你大可以鄙视我,我的脑袋是不灵光。尽管这是一个简单的问题,但是我还是简单的记录一下我的理解。

  问题的起源是“Cocoa Programming For Mac OS X”上一段关于NSCell的叙述:

NSControl inherits from NSView. With its graphics context, NSView is a relatively large and expensive object to create. When the NSButton class was created, the first thing someone did was to create a calculator with 10 rows and 10 columns of buttons. The performance was less than it could have been because of the 100 tiny views. Later, someone had the clever idea of moving the brains of the button into another object (not a view) and creating one big view (called an NSMatrix) that would act as the view for all 100 button brains. The class for the button brains was called NSButtonCell.

— Chapter 17. Custom Views, “For the More Curious: Cells”

现在在此阅读这句话,我似乎已经能够基本理解,不过当时那叫一个困惑啊。为什么用Cell就比Button性能高呢?为什么Cell可以替代Button呢?

我的理解如下(可能并不是很精确):

  • NSButton的继承关系是:NSButton –> NSControl –> NSView –> NSResponder –> NSObject。应该说,是一个很长的继承链了。
  • NSButtonCell的继承关系是:NSButtonCell –> NSCell –> NSObject

比之NSButton,少了两层继承关系。光凭这一点大致就能够解释为什么Cell的性能比Control高很多了。

但是既然Cell和Control都代表了“控件”,那么两者又是怎样的关系呢?

查阅了苹果的文档之后,就发现里面有这么一句话:“The NSButton class uses NSButtonCell to implement its user interface.”

这么一来,一切都清楚了,NSCell是控件的UI显示部分。但是NSCell不是NSView的子类,它又怎么显示自己呢?在NSButton的文档里,又有下面的一段话:

NSButton and NSMatrix both provide a control view, which is needed to display an NSButtonCell object. However, while NSMatrix requires you to access the NSButtonCell objects directly, most of the NSButton class’ methods are “covers” for identically declared methods in NSButtonCell. (In other words, the implementation of the NSButton method invokes the corresponding NSButtonCell method for you, allowing you to be unconcerned with the existence of the NSButtonCell.)

这段话的大意是:

NSButtonNSMatrix能够为NSButtonCell提供一个控制视图,用来实现Cell的显示。不过NSMatrix需要直接操作NSButtonCell对象,而NSButton则不需要。因为它已经“封装”了所有NSButtonCell的同名方法。也就是说,对NSButton调用方法(不是所有的方法),实际上是对NSButtonCell调用方法,调用的时候,我们甚至可以无需知道NSButtonCell的存在。

至此,问题解决。甚至,以前没有联系起来的一个问题也解决了:那就是,为什么在Interface Builder中,NSButton总是和NSButtonCell同时存在的——原因,当然也是上面的那段话啦~另外,在Interface Builder里,NSButtonNSButtonCell的Inspector里的属性也基本相同,也是因为上述原因。

一点题外话:

UIKit里没有NSCell的对应类。原因并不是很清楚。不过UIKit里的类的继承结构也与AppKit有所不同。比如,NSTableView的列:NSTableColumn采用的是Cell的显示机制;而UITableView则采用的是UITableViewCell。前者继承自NSObject,后者继承自UIView

关于这样的区别在性能上的差别,我不敢妄下结论,也没法随便比较——毕竟是两个不同平台。似乎在iOS平台上,UITableView的Cell会在离开显示区域的时候被release掉——这可能是为什么iOS平台没有采用UICell(没有这个类的!!!)的原因之一。

不过,我感觉UITableViewNSTableView更加灵活,自定义也更加方便——因为每个UITableViewCell可以很方便的用一个Custom View来做界面;而NSTableColumn则依赖于NSCell,要自定义,需要用自定义NSCell的子类,这样会复杂很多。

本文转载自 http://cocoa.venj.me/blog/about-nscell/

关于NSCELL的更多相关文章

  1. 《ARC以及非ARC的讨论》

    ARC的机制是什么?它在那里放入retain/release函数调用? 请停止思考这些问题,把更多的精力放在下面的问题上,比如你的程序逻辑,对象的强,弱引用,对象的所属关系,可能的循环引用等问题上. ...

  2. iOS开发(OC)中的命名规范

    开小差:最近发现自己有一个经验主义的毛病,不太容易接受新的知识,这对从事技术研发的人来说不太合理,需要改之. 正文:通过读写大量代码我有自己的一套编程思路和习惯,自认为自己的编码习惯还是不错的,代码结 ...

  3. [iOS翻译]Cocoa编码规范

        简介: 本文整理自Apple文档<Coding Guidelines for Cocoa>.这份文档原意是给Cocoa框架.插件及公共API开发者提供一些编码指导,实质上相当于Ap ...

  4. ios下划线变量:为什么变量前要加下划线才有用?

    先看一段代码.   复制代码 appdelegate.h @property (weak) IBOutlet NSMatrix *StockType; @property (weak) IBOutle ...

  5. Xcode 插件开发

    我最近一年来都在开发ios应用,不过感觉公司的app维护起来非常麻烦. 因为公司要为很多个企业订做app,每个app的功能基本相同,只是界面上的一些图片和文字要换掉,功能也有一些小改动.考虑到代码维护 ...

  6. iOS开发——OC篇&消息传递机制(KVO/NOtification/Block/代理/Target-Action)

     iOS开发中消息传递机制(KVO/NOtification/Block/代理/Target-Action)   今晚看到了一篇好的文章,所以就搬过来了,方便自己以后学习 虽然这一期的主题是关于Fou ...

  7. iOS-OC命名规范

    IOS开发(OC)中的命名规范 正文:通过读写大量代码我有自己的一套编程思路和习惯,自认为自己的编码习惯还是不错的,代码结构也算清晰,因为我一直以来都是代码看的多写的多,但是总结的比较少,知识经常不成 ...

  8. [转]Hooked on DTrace

    source link: 1.http://blog.bignerdranch.com/1907-hooked-on-dtrace-part-1/ 2.http://blog.bignerdranch ...

  9. IOS开发 Application Kit框架的线程安全

    以下部分介绍了Application Kit框架的线程安全. 非线程安全类 以下这些类和函数通常是非线程安全的.大部分情况下,你可以在任何线程使用这些类,只要你在同一时间只有一个线程使用它们.查看这些 ...

随机推荐

  1. XMU 1050 Diffuse Secret 【最短路】

    1050: Diffuse Secret Time Limit: 500 MS  Memory Limit: 64 MBSubmit: 10  Solved: 8[Submit][Status][We ...

  2. 并不对劲的bzoj3214:p3333:[ZJOI2013]丽洁体

    题目大意 有三个由若干个单词组成的字符串\(T,A,B,C(|T|,|A|,|B|,|C|\leq 5*10^4,单词长度\leq5,每个单词出现次数\leq500)\) 求从\(T\)中至少删去多少 ...

  3. 并不对劲的bzoj4827:loj2020:p3723:[AHOI/HNOI2017]礼物

    题目大意 有两个长度为\(n\)(\(n\leq5*10^4\))的数列\(x_1,x_2,...,x_n\)和\(y_1,y_2,...,y_n\),两个数列里的数都不超过\(m\)(\(m\leq ...

  4. 并不对劲的bzoj1861: [Zjoi2006]Book 书架

    传送门-> 这题的正确做法是splay维护这摞书. 但是并不对劲的人选择了暴力(皮这一下很开心). #include<algorithm> #include<cmath> ...

  5. Memcache存储大数据的问题(大于1m)

    Memcached存储单个item最大数据是在1MB内,如果数据超过1M,存取set和get是都是返回false,而且引起性能的问题. 我们之前对排行榜的数据进行缓存,由于排行榜在我们所有sql se ...

  6. .NET MVC API返回JSON对象

    方法多种,自己目前采用的是自定义返回格式的方法,不需要修改配置文件. 辅助类: public class ApiResponseHelper { public static HttpResponseM ...

  7. 搭建CARDBOARD+ANDROID+unity3d的VR开发环境

    一.下载最新unity3d(u3d官网) 二.下载最新cardboardsdkforunity(https://github.com/googlesamples/cardboard-unity) 三. ...

  8. E20180309-hm-xa

    conformance   n. 顺应,一致; symmetric   adj. 相称性的,均衡的; raw  adj. 生的,未加工的; 无经验的; 新近完成的; 发炎的,疼痛的; exceed  ...

  9. python 面向对象六 动态添加方法 __slots__限制动态添加方法

    一.动态添加属性 >>> class Student(object): pass >>> st = Student() >>> st.name = ...

  10. [浏览器美化]去除 Firefox 当前选中标签页顶端的线条

    Firefox 当前选中的标签页的最上方会显示有一条线,我觉得很丑,如图: 在地址栏输入 about:support ,然后点击打开目录. 在此目录中创建一个 chrome 文件夹(若没有),然后进入 ...