面试题笔记3

<span style="font-family:SimSun;font-size:18px;">1、 描述应用程序的启动顺序。</span>
<span style="font-family:SimSun;font-size:18px;">程序入口main函数创建UIApplication实例和UIApplication代理实例。在UIApplication代理实例中重写启动方法,设置根ViewController。在第一ViewController中添加控件,实现应用程序界面。</span>

2、 为什么很多内置类如UITableViewControl的delegate属性都是assign而不是retain?请举例说明。

常见的delegate往往是assign方式的属性而不是retain方式 的属性,赋值不会增加引用计数,就是为了防止delegation两端产生不必要的循环引用。
 
 
循环引用所有的引用计数系统,都存在循环应用的问题。例如下面的引用关系:   
 •    对象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又是a, 如果这个delegate是retain方式的,那基本上就没有机会释放这两个对象了。自己在设计使用delegate模式时,也要注意这点。因为循环引用而产生的内存泄露也是Instrument无法发现的,所以要特别小心。

众所周知,iOS开发的时候,使用ARC的话,dealloc函数是不需要实现的,写了反而会出错。

但有些特殊的情况,dealloc函数还是需要的。

比如,在画面关闭的时候,需要把ViewController的某些资源释放,

    在viewDidDissppear不一定合适,viewDidUnload一般情况下只在memory warning的时候才被调用。

    不用ARC的情况下,我们自然会想到dealloc函数。

    其实ARC环境下,也没有把dealloc函数禁掉,还是可以使用的。只不过不需要调用[supper dealloc]了。

举个例子,画面上有UIWebView,它的delegate是该画面的ViewController,在WebView载入完成后,需要做某些事情,比如,把indicator停掉之类的。

    如果在WebView载入完成之前关闭画面的话,画面关闭后,ViewController也释放了。但由于WebView正在载入页面,而不会马上被释放,等到页面载入完毕后,回调delegate(ViewController)中的方法,由于此时ViewController已经被释放,所以会出错。(message sent to deallocated instance)

解决办法是在dealloc中把WebView的delegate释放。

-(void)dealloc {

    self.webView.delegate = nil;

}

delegate的释放

delegate属性的赋值一般为self,虽然声明时assign,但在相关的view释放时,在之前先释放掉delegate

情况一

if (_loadingContentView) {
        _loadingContentView.delegate = nil;
        [_loadingContentView removeFromSuperview];
    }

情况二 

self.partGridView.uiGridViewDelegate = nil;
 self.partGridView = nil;

3、 使用UITableView时候必须要实现的几种方法?

在UITableView的UITableViewDataSourse中有两个方法必须实现:

@required
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

4、写一个便利构造器方法。

//便利构造区中要使用autorelease
+ (Student *)studentWithName:(NSString *)name
{
Student * student = [[[Student alloc] init] autorelease];
return student;
}

5.UIImage初始化一张图片有几种方法?简述各自的优缺点。

imageNamed:

它的加载流程如下:

系统回去检查系统缓存中是否存在该名字的图像,如果存在则直接返回;如果系统缓存中不存在该名字的图像,则会先加载到缓存中,在返回该对象。

观察上面的操作我们发现系统会缓存我们使用imageNamed:方法加载的图像时候,系统会自动帮我们缓存。这种机制适合于那种频繁用到界面贴图累的加载,但如果我们需要短时间内频繁的加载一些一次性的图像的话,最好不要使用这种方法。效率高,但是会导致内存泄露,无法及时释放,程序结束才释放,API中这样写道:

If you have an image file that will only be displayed once and wish to ensure that it does not get added to the system’s cache, you should instead create your image using imageWithContentsOfFile:. This will keep your single-use image out of the system image cache, potentially improving the memory use characteristics of your app.

2、imageWithContentsOfFile:和initWithContentsOfFile:方法

这两个方法跟前一个方法一样都是完成从文件加载图像的功能。但是不会经过系统缓存,直接从文件系统中加载并返回。

顺便提一下,当收到内存警告的时候,系统可能会将UIImage内部的存储图像的内存释放,下一次需要绘制的时候会重新去加载。

[UIImage imageWithContentsOfFile:path];根据包中图片路径创建UIImage,能够及时释放

6、回答person的retainCount值,并解释为什么

Person * per = [[Person alloc]init];

self.person = per;

若person的属性是retain,则引用计数为2,

若person的属性为assign, 则引用计数为1.

7、这段代码有什么问题吗:

@implementation Person
- (void)setAge:(int)newAge {
self.age = newAge;
}
@end

在setter方法中使用self.age相当于再次调用setter方法,造成循环引用。

9、 截取字符串”20 | http://www.baidu.com”中,”|”字符前面和后面的数据,分别输出它们。

 NSString * str  = @"20 | http://www.baidu.com";
 NSArray * array = [str componentsSeparatedByString:@"|"];

10、用obj-c写一个冒泡排序



 
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值