作为一个初学者,我一直很弄不明白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. egrep grep -E

    egrep执行效果与"grep-E" Linux egrep命令用于在文件内查找指定的字符串. egrep执行效果与"grep-E"相似,使用的语法及参数可参照 ...

  2. 临时表 数据在 内存 转移时间 将160秒的创建临时表时间放入定时任务 不到1秒的求和时间 hadoop 引入Hadoop 分布式计算

    SELECT SUM(pv) as pv_t  FROM 行 112247817表类型 InnoDB自动递增值 1082428327行格式  Compact索引长度 8.60 GB (9,235,93 ...

  3. jquery ui tabs详解(中文)

    1 属性1.11 ajaxOptions,当选项卡加载内容时,添加一个ajax选项.只有ajax时,添加的ajax选项才起作用.默认值为null.上面的例子中,添加了beforeSend和succes ...

  4. POJ 1269 Intersecting Lines(线段相交,水题)

    id=1269" rel="nofollow">Intersecting Lines 大意:给你两条直线的坐标,推断两条直线是否共线.平行.相交.若相交.求出交点. ...

  5. lucene DocValues——本质是为通过docID查找某field的值 看图

    Why DocValues? The standard way that Solr builds the index is with an inverted index. This style bui ...

  6. UITabBarController简单介绍

    一.简单介绍 UITabBarController和UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型的例 ...

  7. 洛谷P2943 清理——DP

    题目:https://www.luogu.org/problemnew/show/P2943 一眼看去就有个 n^2 的做法:f[i] = min{ f[j] + num( i - j ) * num ...

  8. AutoMapper封装类

    /// <summary> /// AutoMapper扩展帮助类 /// </summary> public static class AutoMapperHelper { ...

  9. webpack -v显示的版本与package.json的devDependencies节点显示的webpack版本不一致的问题

    最近在学习webpack,遇到个奇葩的问题.就是安装完成webpack后,查看安装的webpack版本与package.json中显示的版本不一致, webpack是局部安装的,非全局安装, 命令1: ...

  10. POJ3233:Matrix Power Series(矩阵快速幂+递推式)

    传送门 题意 给出n,m,k,求 \[\sum_{i=1}^kA^i\] A是矩阵 分析 我们首先会想到等比公式,然后得到这样一个式子: \[\frac{A^{k+1}-E}{A-E}\] 发现要用矩 ...