【iOS面试】iOS面试经典题 NO.7

1.OC中,与alloc语义相反的方法是dealloc还是release?

与 retain语义相反的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么? 答:alloc与dealloc语意相反,alloc是创建变量,dealloc是释放变量。 retain 对应release,retain 保留一个对象。调用之后,变量的计数加1。或许不是很明显,在这有例为证:
- (void) setName : (NSString*) name {
[name retain];
[myname release];
myname = name;
}
我们来解释一下:设想,用户在调用这个函数的时候,他注意了内存的管理,所以他小心的写了如下代码:
NSString * newname = [[NSString alloc] initWithString: @”John”];
[aClass setName: newname];
[newname release];
我 们来看一看newname的计数是怎么变化的。首先,它被alloc,count = 1; 然后,在setName中,它被retain, count = 2; 最后,用户自己释放newname,count = 1,myname指向了newname。这也解释了为什么需要调用[myname release]。我们需要在给myname赋新值的时候,释放掉以前老的变量。retain 之后直接dealloc对象计数器没有释放。alloc 需要与release配对使用,因为alloc 这个函数调用之后,变量的计数加1。所以在调用alloc 之后,一定要调用对应的release。另外,在release一个变量之后,他的值仍然有效,所以最好是后面紧接着再var = nil。
2.在一个对象的方法里面:self.name = “object”;和name =”object”有什么不同吗?

答:self.name = “object”会调用对象的setName()方法,name = “object”会直接把object赋值给当前对象的name 属性。
[backcolor=transparent][backcolor=transparent]

3.这段代码有什么问题吗?
[backcolor=transparent]@implementation Person
[backcolor=transparent]- (void)setAge:(int)newAge {
[backcolor=transparent]self.age = newAge;
[backcolor=transparent]}
[backcolor=transparent]@end 

答:会进入死循环。 出现死循环,循环调用。
4. 什么是retain count?

答:引用计数(ref count或者retain count)。对象的内部保存一个数字,表示被引用的次数。例如,某个对象被两个指针所指向(引用)那么它的retain count为2。需要销毁对 象的时候,不直接调用dealloc,而是调用release。release会 让retain count减1,只有retain count等于0,系统才会调用dealloc真正销毁这个对象。
5.以下每行代码执行后,person对象的retain count分别是多少?
Person *person = [[Person alloc] init]; count 1
[person retain]; count 2
[person release];count 1
[person release];retain count = 1;
6.为什么很多内置类如UITableViewController的delegate属性都是assign而不是retain的?

答:会引起循环引用。
7. 定义属性时,什么情况使用copy,assign,和retain ?

答:assign用于简单数据类型,如NSInteger,double,bool,retain 和copy用户对象,copy用于当 a指向一个对象,b也想指向同样的对象的时候,如果用assign,a如果释放,再调用b会crash,如果用copy 的方式,a和b各自有自己的内存,就可以解决这个问题。retain 会使计数器加一,也可以解决assign的问题。另外:atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操 作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic,setter函数会变成下面这样:
if (property != newValue) { [property release]; property = [newValue retain]; }
8. 对象是在什么时候被release的?

答:autorelease实际上只是把对release的调用延迟了,对于每一个Autorelease,系统 只是把该Object放入了当前的Autorelease pool中,当该pool被释放时,该pool中的所有Object会被调用Release。对于每一个Runloop, 系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个象CallStack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object(就是autorelease的对象)会被release。那什么是一个Runloop呢? 一个UI事件,Timer call, delegate call, 都会是一个新的Runloop。那什么是一个Runloop呢? 一个UI事件,Timer call, delegate call, 都会是一个新的Runloop。
9.这段代码有什么问题,如何修改?
for (int i = 0; i < someLargeNumber; i++)
{
NSString *string = @”Abc”;
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
SLog(@“%@”, string);
}

 答:会内存泄露,
for(int i = 0; i<1000;i++){
NSAutoreleasePool * pool1 = [[NSAutoreleasePool alloc] init];
NSString *string = @”Abc”;
string = [string lowercaseString];
string = [string stringByAppendingString:@"xyz"];
NSLog(@”%@”,string);
[pool1 drain];
}

你可能感兴趣的:(【iOS面试】iOS面试经典题 NO.7)