ios面试攻略(3.0)

来源:互联网 发布:android分享功能源码 编辑:程序博客网 时间:2024/05/07 21:34

来自:蓝色维度

一、属性相关

1.在一个对象的方法里面: self.name = “object”;  name ”object” 有什么不同吗?
答:self.name = “object”会调用对象的setName()方法,name = “object”会直接把object赋值给当前对象的name属性。
2.
这段代码有什么问题吗:
@implementation Person
- (void)setAge:(int)newAge 
{

self.age = newAge;
}
答:在进行age属性进行.的赋值时,会调用此方法的setAge方法,这样会进入无休止的循环调用中导致crash.
3.
定义属性时,什么情况使用copyassign,和retain?
答:readwrite 是可读可写特性;需要生成getter方法和setter方法时
readonly 
是只读特性 只会生成getter方法 不会生成setter方法 ;不希望属性在类外改变
assign 
赋值特性setter方法将传入参数赋值给实例变量;仅设置变量时;
retain 
表示持有特性setter方法将传入参数先保留,再赋值,传入参数的retain count+1;
copy 
表示赋值特性setter方法将传入对象复制一份;需要完全复制一份新的变量时。
// more
nonatomic 
非原子操作,决定编译器生成的setter getter是否是原子操作,atomic表示多线程安全,一般使用nonatomic
assign
用于简单数据类型,如NSInteger,double,bool,retain copy用户对象,copy用于当 a指向一个对象,b也想指向同样的对象的时候,如果用assigna如果释放,再调用bcrash,如果用copy 的方式,ab各自有自己的内存,就可以解决这个问题。retain 会使计数器加一,也可以解决assign的问题。另外:atomicnonatomic用来决定编译器生成的gettersetter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomicsetter函数会变成下面这样:
if (property != newValue) {
[property release];
property = [newValue retain];
}

4.写一个setter方法用于完成@property nonatomic,retainNSString *name,
写一个setter方法用于完成@propertynonatomiccopyNSString *name
答:// 这里主要是注意顺序,先要reain传入参数,再release原来的属性。防止namestr是同一个变量时发生错误。
// retain
- (void) setName : (NSString*) str {
[str retain];
[name release];
name = str;
}
// copy
- (void)setName:(NSString *)str
{
id t = [str copy];
[name release];
name = t;
}

5.为什么很多内置类如UITableViewControllerdelegate属性都是assign而不是retain的?
答:会引起循环引用,导致内存无法释放

 

二、UIViewController

1.ViewController  loadView, viewDidLoad, viewDidUnload 分别是在什么时候调用的?
在自定义ViewController的时候这几个函数里面应该做什么工作?
答:当ViewControll被初始化后,调用self.view属性时,如果viewnil的话,会调用loadView方法。loadView方法调用完成后,会调用viewDidLoad
ViewController收到内存不足的警告时,6.0以下版本会调用viewDidUnload方法。
这三个方法,在调用时,首先应该调用super类的同名方法,否则有可能引起循环调用crash
loadView
一般用于使用xib文件的情况,我们可以不重写这个方法。
viewDidLoad
里可以加载一些我们自己的view
viewDidUnload
里实现将retain view release,如果是retainIBOutlet view 属性则不要在这里release,IBOutlet会负责release 
loadView
viewDidLoad里面加载的内容和viewDidUnload里面卸载的内容应该对应,否则容易内存泄露或者过度释放。

2.ViewController  didReceiveMemoryWarning 是在什么时候被调用的?默认的操作是什么?
答:当ViewController收到内存不足的警告时,6.0以下版本会调用viewDidUnload方法。
默认操作是调用super的同名方法,将viewControllerview的所有subView移除,将view本身释放。

  

三、C语言相关

1.sizeofstrlen的区别和联系?
答:两者的联系是,都可以返回一个长度。
sizeof
返回的是变量或类型所占的字节数。strlen返回的是字符串的长度。
sizeof
是关键字,strlen是库函数。

2. 下列两行代码有什么区别?
char a[] = “string”;
char *b = “string”;
a
是字符数组,b一个字符串,两者sizeof取值不同。

3. 下列代码会输出什么?
#define SQ(x) (x*x)
int main()
{
int b = 3;
int a = SQ(b + 2);
printf(“%d”, a);
return 0;
}

=b+2*b+2

11,不是25.主是要宏的直接替换问题。定义宏的时候元素上要加小括号.

4. 下列代码有什么问题?
char *foo(int n)
{
char buf[32];
buf[0] = (n != 0) ? ‘T’ : ‘F’;
buf[1] = 0;
return buf;
}
返回的是野指针。

5. 下列代码有什么问题?若有错误请改正。
void swap(int *p1, int *p2)
{
int *p = p1;
p1 = p2;
p2 = p;
}
无法实现交换两个指针,参数应该用指针的指针。

6.  char *p = malloc(32);  sizeof(p) 的值是什么?
32
位机器上是4

7. 用递归方式和非递归方式写函数将一个字符串按字节反转,函数原型如下:
char *reverse(char *str);
非递归:
char *reverse(char *str)
{
if (str == NULL || strlen(str) <= 1) {
return str;
}
int len = strlen(str);
char* b = (char*)malloc(len+1);// 
外部去释放
strcpy(b, str);
for (int i=0; i
 char x = b[i];
b[i] = b[len-i-1];
b[len-i-1] = x;
}

return b;
}

递归:
char *reverse(char *str)
{
if (str == NULL || strlen(str) <= 1) {
return str;
}

int len = strlen(str);

char e[] = {str[len-1],0};
char s[] = {str[0],0};

char* b = (char*)malloc(len-1);
strncpy(b, str+1,len-2);

char* c = (char*)malloc(len+1);// 外部去释放,递归时可能有泄露
strcat(c, e);
strcat(c, reverse(b));
strcat(c, s);

free(b);
return c;
}

8. 为什么在析构函数中不应该抛出异常?
因为析构函数主要是已经进入清理内存的阶段,这时抛出异常的话没有地方去捕捉,会引起系统异常退出。

9.sprintf,strcpy,memcpy使用上有什么要注意的地方
strcpy
是一个字符串拷贝的函数,它的函数原型为strcpy(char *dst, const char *src);
src开始的一段字符串拷贝到dst开始的内存中去,结束的标志符号为’\0′,由于拷贝的长度不是由我们自己控制的,所以这个字符串拷贝很容易出错。具备字符串拷贝功能的函数有memcpy,这是一个内存拷贝函数,它的函数原型为memcpy(char *dst, const char* src, unsigned int len);
将长度为len的一段内存,从src拷贝到dst中去,这个函数的长度可控。但是会有内存叠加的问题。
sprintf
是格式化函数。将一段数据通过特定的格式,格式化到一个字符串缓冲区中去。sprintf格式化的函数的长度不可控,有可能格式化后的字符串会超出缓冲区的大小,造成溢出。

10 程序在内存中运行时,内存分几个区?各自用途?
答:栈区 由编译器自动分配释放存放函数的参数值,局部变量的值等。在高级语言中不需要显式的分配和释放
堆区 一般由程序员手动分配释放,如果不释放可有由OS释放。
数据区 存储全局和静态变量。初始化的全局和静态变量在一块区域,未初始化的放在相邻的一块区域,程序结束后由系统释放。
代码区 存放函数体的二进制代码。

11 引用与指针有什么区别?
答:引用是给变量起一个别名 也就是一个变量有两个名字 他们是同一块空间
指针是分配一块内存用来保存变量的地址 间接引用变量

0 0
原创粉丝点击