疑难知识点积累

1、static作用(静态变量与函数,全局与局部的使用范围)

(1)函数体内 static 变量的作用范围为该函数体,不同于 auto 变量,该变量的内存只被分配一次

因此其值在下次调用时仍维持上次的值;

(2)在模块内的 static 全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

(3)在模块内的 static 函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明

它的模块内;

(4)在类中的 static 成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

(5)在类中的 static 成员函数属于整个类所拥有,这个函数不接收 this 指针,因而只能访问类的static 成员变量

2、Object-C的内存管理?

(1)当你使用new,alloc和copy方法创建一个对象时,该对象的保留计数器值为1.需要手动向该对象发送一条release或autorelease消息,才能销毁对象。

(2)当你通过任何其他方法获得一个对象时,则假设该对象的保留计数器值为1,而且已经被设置为自动释放,不需要手动释放。如果你打算在一段时间内拥有该对象,则需要保留它并确保在操作完成时释放它.

(3)如果你保留了某个对象,你需要(最终)释放或自动释放该对象,必须保持retain方法和release方法的使用次数相等.

3、为什么很多内置的类,如TableViewController的delegate的属性是assign不是retain?

循环引用,所有的引用计数系统,都存在循环应用的问题。

例如下面的引用关系:对象a创建并引用到了对象b,对象b创建并引用到了对象c,对象c创建并引用到了对象b.

这时候b和c的引用计数分别是2和1。当a不再使用b,调用release释放对b的所有权,因为c还引用了b,所以b的引用计数为1,b不会被释放。b不释放,c的引用计数就是1,c也不会被释放。从此,b和c永远留在内存中。这种情况,必须打断循环引用,通过其他规则来维护引用关系。

比如,我们常见的delegate往往是assign方式的属性而不是retain方式的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。如果一个UITableViewController 对象a通 过retain获取了UITableView对象b的所有权,这个UITableView对象b的delegate(c)又是a,如果这个delegate是 retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点

4、定义属性时,什么情况使用copy、assign、retain?

assign用于简单数据类型,如NSInteger,double,bool,

retain和copy用于对象,copy相当于两个房间两把钥匙,retain相当于一个房间两把钥匙。

另外:atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。

5、对象是什么时候被release的?

引用计数为0时。

autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统只是把该Object放入了当前的 Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。

待深入理解runloop:

对于每一个Runloop,系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个 Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object(就是autorelease的对 象)会被release。那什么是一个Runloop呢?一个UI事件,Timer call, delegate call, 都会是一个新的 Runloop。

6、tableView的重用机制?

查看UITableView头文件,会找到NSMutableArray*  visibleCells和NSMutableDictnery* reusableTableCells(iOS 7 没有?)两个结构。visibleCells内保存当前可见的 cells,reusableTableCells保存可重用的cells。

TableView显示之初,reusableTableCells为空,那么 tableView dequeueReusableCellWithIdentifier:CellIdentifier返回nil。开始的cell都是通过 [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 来创建,而且cellForRowAtIndexPath只是调用最大显示cell数的次数。

比如:有100条数据,iPhone一屏最多显示10个cell。程序最开始显示TableView的情况是:

(1)用 [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] 创建10次cell,并给cell指定同样的重用标识(当然,可以为不同显示类型的cell指定不同的标识),并且10个cell全部都加入到 visibleCells数组,reusableTableCells为空。

(2)向下拖动tableView,当cell1完全移出屏幕,cell1移出visiableCells,cell1加入到reusableTableCells。

(3)接着向下拖动tableView,因为reusableTableCells中已经有值,所以,当需要显示新的 cell,cellForRowAtIndexPath再次被调用的时 候,tableView dequeueReusableCellWithIdentifier:CellIdentifier,返回cell1。 cell1加入到visiableCells,cell1移出reusableTableCells;cell2移出 visiableCells,cell2加入到reusableTableCells。之后再需要显示的Cell就可以正常重用了。


9、类目的作用?与继承的区别

类目中方法的调用和原始类中的方法一样,类目中的方法也会被子类继承;

类目把一个很大的类分成多个小块来开发,更好维护;

类目就只能添加类方法,不能添加成员变量或者属性,继承就可以添加变量;

如果类目中写了一个跟原始类一样的方法,类目方法优先被访问;

类目的命名规则:类名+扩展方法。

10、怎么理解MVC,在Cocoa中MVC是怎么实现的?

Model: 代表你的应用程序是什么(不是怎么展现)

Controller: 控制你的Model怎么展现给用户(UI逻辑)

View: Controller的奴隶。。。

(1)Model,Controller,View相互通讯的规则:

Controller可以直接和Model通信

Controller也可以直接和View通信

Model和View永远不能直接通信

(2)iOS中View和Controller的通信是透明和固定的,主要通过outlet和action实现

View使用Delegate接口和Controller同步信息

View不直接和数据通信,使用dataSource接口从Controller处获取数据

View的delegate和dataSource一般就是Controller

Controller负责为View翻译和格式化Model的数据

Model使用Notification & KVO的方式分发数据更新信息,Controller可以有选择的监听自己感兴趣的信息。

View也可以监听广播信息,但一般不是Model发出的信息

一个完整的App就是很多MVC的集合

11、delegate和notification区别,分别在什么情况下使用?

Delegate:消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate机制使得接收者可以改变发送者的行为。通常发送者和接收者的关系是直接的一对多的关系。

Notification:消息的发送者告知接收者事件已经发生或者将要发送,仅此而已,接收者并不能反过来影响发送者的行为。通常发送者和接收者的关系是间接的多对多关系。

(1)效率是delegate比nsnotification高, delegate方法比notification更加直接

(2)最典型的特征是,delegate方法往往需要关注返回值,也就是delegate方法的结果。比如-windowShouldClose:,需要关心返回的是yes还是no。所以delegate方法往往包含should这个很传神的词。 也就是好比你做我的delegate,我会问你我想关闭窗口你愿意吗?你需要给我一个答案,我根据你的答案来决定如何做下一步。相反的,notification最大的特色就是不关心接受者的态度,我只管把通告放出来,你接受不接受就是你的事情,同时我也不关心结果。所以 notification往往用did这个词汇,比如NSWindowDidResizeNotification,那么nswindow对象放出这个 notification后就什么都不管了也不会等待接受者的反应。

(3)两个模块之间联系不是很紧密,就用notification传值,例如多线程之间传值用notificaiton。

(4)delegate只是一种较为简单的回调,且主要用在一个模块中,例如底层功能完成了,需要把一些值传到上层去,就事先把上层的函数通过 delegate传到底层,然后在底层call这个delegate,它们都在一个模块中,完成一个功能。

12、属性变量与实例变量的差异

写在.h{}里的变量叫实例变量,这里面的变量默认是受保护的,子类可以访问,外界不能访问。

但是如果把实例变量声明为@public,外界就可以访问,但是与属性变量不同,属性变量通过.访问,实例变量通过->访问

.m文件里面的变量都是私有的,只有实例内部能访问。


13、当你为某个属性重写setter和getter中的其中一个方法,或者都没重写,编译器都会自动帮你添加上@synthesize语句。如果你在.m文件中同时重写了该属性的getter和setter方法,那么你就必须去手动去创建这个属性的实例变量,即手动加上@synthesize语句。


为什么关联到代码里的IBOutlet变量是weak类型。因为视图层已经强引用了该IBOutlet变量,所以控制器层就不需要再去强引用该变量。


instancetype这个类型会告诉编译器,这个方法返回的对象的类型和接受消息的对象类型一样。


当一个名为a的属性,声明在头文件中,并且为只读类型。但是,你在实现文件中想对a属性进行写操作。就可以在实现没见的类扩展中重新声明这个a属性,声明为readwrite。不过,一般情况下,readwrite是默认的。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值