IOS面试题object-c 71-80

时间:2024-03-11 12:42:30
71. 简单介绍下NSURLConnection类及 + sendSynchronousRequest:returningResponse:error:与– initWithRequest:delegate:两个方法的区别?
NSURLConnection 主要用于网络访问,其中 + sendSynchronousRequest:returningResponse:error:是同步访问数据,即当前线程会阻塞,并等待request的返回的response,而– initWithRequest:delegate:使用的是异步加载,当其完成网络访问后,会通过delegate回到主线程,并其委托的对象。
????????????????????????
72. Object-C有私有方法吗?私有变量呢?

objective-c – 里面的方法只有两种, 静态方法和实例方法.

这似乎就不是完整的面向对象了, 按照OO的原则就是一个对象只暴露有用的东西.

如果没有了私有方法的话, 对于一些小范围的代码重用就不那么顺手了.

在类里面声名一个私有方法

@interface  Controller : NSObject {

        NSString *something;

}


+ (void)  thisIsAStaticMethod;


– (void)  thisIsAnInstanceMethod;


@end


@interface Controller

(private) -(void)  thisIsAPrivateMethod;


@end


@private可以用来修饰私有变量

????????????????????????
 73. Object-C有多继承吗?

Object-c的类没有多继承, 只支持单继承, 如果要实现多继承的话, 可以通过类别和协议的方式来实现, OC类似于多继承, 是在 用protocol委托代理来实现的;

可以实现多个接口, 通过实现多个接口可以完成C++的多重继承;

Category是类别, 一般情况用分类好, 用Category去重写类的方法, 仅对本Category有效, 不会影响到其他类与原有类的关系

????????????????????????
 74. 内存管理 Autorelease、retain、copy、assign的set方法和含义?

1).你初始化(alloc/init)的对象,你需要释放(release)它。

例如:
NSMutableArray aArray = [[NSArray alloc] init];  后,需要 [aArray release];

2).你retaincopy的,你需要释放它。

例如:
[aArray retain] 后,需要 [aArray release];

3).被传递(assign)的对象,你需要斟酌的retainrelease

例如:
obj2 = [[obj1 someMethod] autorelease];

对象2接收对象1的一个自动释放的值,或传递一个基本数据类型(NSInteger,NSString)时:你或希望将对象2进行retain,以防止它在被使用之前就被自动释放掉

但是在retain后,一定要在适当的时候进行释放

关于索引计数(Reference Counting)的问题
retain值 = 索引计数(Reference Counting)

NSArray对象会retain(retain值加一)任何数组中的对象。

NSArray被卸载(dealloc)的时候,所有数组中的对象会 被 执行一次释放(retain值减一)。

不仅仅是NSArray,任何收集类(Collection Classes)都执行类似操作。

例如 NSDictionary,甚至UINavigationController

Alloc/init 建立的对象,索引计数为1。

无需将其再次 retain。 

[NSArray array]和[NSDate date]等“方法”建立一个索引计数为1的对象,但是也是一个自动释放对象

所以是本地临时对象,那么无所谓了。

如果是打算在全Class中使用的变量(iVar),则必须retain它。

缺省的类方法返回值都被执行了“自动释放”方法。(*如上中的NSArray)
在类中的卸载方法“dealloc”中,release所有未被平衡的NS对象。(*所有未被autorelease,而retain值为1的)
????????????????????????
75. 简述C语言和Object-C 如何混用?
1).obj-c的编译器处理后缀为m的文件时可以识别obj-c和c的代码处理mm文件可以识别obj-c,c,c++代码,但cpp文件必须只能c/c++代码,而且cpp文件include的头文件中,也不能出现obj-c的代码,因为cpp只是cpp
2).在mm文件中混用cpp直接使用即可,所以obj-c混cpp不是问题

3).在cpp中混用obj-c其实就是使用obj-c编写的模块是我们想要的。

如果模块以类实现,那么要按照cpp class的标准写类的定义头文件中不能出现obj-c的东西,包括#import cocoa的。

实现文件中,即类的实现代码中可以使用obj-c的东西,可以import, 只是后缀是mm

如果模块以函数实现,那么头文件要按c的格式声明函数实现文件中,c++函数内部可以用obj-c,但后缀还是mm或m

总结:

只要cpp文件和cpp include的文件中不包含obj-c的东西就可以用了cpp混用obj-c的关键是使用接口,而不能直接使用 实现代 码,实际上cpp混用的是obj-c编译后的o文件,这个东西其实是无差别的,所以可以用。

obj-c的编译器支持cpp

????????????????????????
76. 解释什么时候用Delegate,什么时候用Notification?
delegatenotification都是为了在不同的对象之间传递数据,那么何时该使用delegate,何时该使用notification呢?
1.参数的不同
使用delegate参数更加直观,使用notification参数不那么直观,所以能使用delegate的地方,尽量使用delegate
2.传递的长度
有时候你的页面会一次跳好几个页面,那么你想把这个页面的数据传回到底层是很麻烦的事情,因为你要把delegate指针从底层界面一直传上来
3.传递多个数据
当你在同一个对象传递给多个对象,用delegate不可行了。
观察者模式,controllerdefaultNotificationCenter添加自己的notification其他类注册这个notification就可以收到通知,这些类可以在收到通知时做自己的操作(多观察者默认随机顺序发通知给观察者们,而且每个观察者都要等当前的某个观察者的操作做完才能轮到他来操作,可以用NotificationQueue的方式安排观察者的反应顺序,也可以在添加观察者中设定反映时间,取消观察需要在viewDidUnloaddealloc中都要注销)。

delegate针对one-to-one关系,并且reciever可以返回值给sender,notification可以针对one-to-one/many/none,reciever无法返回值给sender.

所以,delegate用于sender希望接受到reciever的某个功能反馈值,

notification用于通知多个object某个事件。
????????????????????????
 77. 用预处理指令#define声明一个常数,用以表明1年中有多少秒?
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
#define 语法的基本知识(例如:不能以分号结束,括号的使用,等等)
懂得预处理器将为你计算常数表达式的值,因此,直接写出你是如何计算一年中有多少秒而不是计算出实际的值,是更清晰而没有代价的。
意识到这个表达式将使一个16位机的整型数溢出 - 因此要用到长整型符号L, 告诉编译器这个常数是的长整型数
????????????????????????
78. 关键字const有什么含意?修饰类呢?static的作用,用于类呢?还有extern c的作用 ?
const 意味着"只读"

const int a;

int const a;

a是一个常整型数。

const int *a;

意味着a是一个指向常整型数的指针(也就是,整型数是不可修改的,但指针可以)。

int * const a;

a是一个指向整型数的常指针(也就是说,指针指向的整型数是可以修改的,但指针是不可修改的)。

int const *a const;

意味着a是一个指向常整型数的常指针(也就是说,指针指向的整型数是不可修改的,同时指针也是不可修改的)。

结论:

关键字const的作用是为给读你代码的人传达非常有用的信息,实际上,声明一个参数为常量是为了告诉了用户这个参数的应用目的。

如果你曾花很多时间清理其它人留下的垃圾,你就会很快学会感谢这点多余的信息。(当然,懂得用const的程序员很少会留下的垃圾让别人来清理的) ?通过给优化器一些附加的信息,使用关键字const也许能产生更紧凑的代码。合理地使用关键字const可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改。简而言之,这样可以减少bug的出现。

1).欲阻止一个变量被改变,可以使用 const 关键字。在定义该 const 变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;

2).对指针来说,可以指定指针本身为 const,也可以指定指针所指的数据为 const,或二者同时指定为 const;

3).在一个函数声明中,const 可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;

4).对于类的成员函数,若指定其为 const 类型,则表明其是一个常函数,不能修改类的成员变量;

5).对于类的成员函数,有时候必须指定其返回值为 const 类型,以使得其返回值不为“左值”。
????????????????????????
79. 关键字Volatile有什么含意?

一个定义为 volatile的变量是说这变量可能会被意想不到地改变,这样,编译器不会去假设这个变量的值了。

精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。

下面是volatile变量的几个例子:
并行设备的硬件寄存器(如:状态寄存器)
一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
多线程应用中被几个任务共享的变量

????????????????????????
80. 参数既可以是const还可以是volatile吗? 指针可以是volatile 吗?解释为什么
1).是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2).是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
????????????????????????