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

    [root@hadoop1 log]# netstatActive Internet connections (w/o servers)Proto Recv-Q Send-Q Local Addres ...

  2. beego07----web博客

    conf/app.conf appname = blog1 httpport = 8080 runmode = dev name=admin pwd=admin controllersmy/attac ...

  3. FMDB数据库队列

    一.代码示例 1.需要先导入FMDB框架和头文件,由于该框架依赖于libsqlite库,所以还应该导入该库. 2.代码如下: 1 // 2 // YYViewController.m 3 // 05- ...

  4. git 一次删除所有删除的文件

    /*********************************************************************************** * git 一次删除所有删除的 ...

  5. linux内存管理之uboot第一步

    在进入讲解linux内存管理的kernel阶段以前,了解一下uboot阶段是如何准备好内存物理设备的,这是非常有意义的.通常进入到linux内核阶段之后,对内存芯片的物理特性寄存器访问是比较少的,强调 ...

  6. Nvidia GPU 算力查询

    GPU Compute Capability Tesla K80 3.7 Tesla K40 3.5 Tesla K20 3.5 Tesla C2075 2.0 Tesla C2050/C2070 2 ...

  7. 【WIP】rails redis的使用

    创建: 2018/03/17 [任务表]TODO 注: mac版 %开头表示命令行命令 安装    安装 % brew install redis  确认版本 % redis-server --ver ...

  8. .Net Core之Configuration

    ASP.NET CORE 中自动集成了应用配置,支持从以下 源 处获取配置键值对 命令行 环境变量 内存 文件配置 其中文件配置是我们最常用的方式,默认文件是.json的json格式文件,摒弃了以往. ...

  9. 项目Alpha版本发布

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2 这个作业的要求在哪里 https://edu.cnbl ...

  10. EditextText输入类型

    android:inputType="none"--输入普通字符 android:inputType="text"--输入普通字符 android:inputT ...