MRC面试题汇总

No.1

//1.计数器的基本操作
// 假设有狗这个类
// 请找出不合理或者错误的地方
@class Dog;

@interface Person : NSObject
@property (nonatomic,retain) Dog *dog;
@end

@implementation Person//
@end

int main()
{
    Person *p = [[Person alloc] init];
    [p release];
    // [p retain];
    
    Person *p2 = [[Person alloc] init];
    //[p2 dealloc];
    [p2 release];
    
    Person *p3 = [[Person alloc] init];
    
    Dog *d = [[Dog alloc] init];
    
    
    p3.dog = d;
    //[d release];
    [p3 release];
    return0;
}

No.2 @property使用

// 假设有Dog类、Car类
// 请找出不合理或者错误的地方
@interface Person : NSObject
@property (nonatomic, assign) Car *car;//要使用retain不能使用assign
@property (nonatomic,atomic, retain) int age;//nonatomic和atomic是一组相对应的函数,只可用一个,int age是个变量不是对象不存在retain要用assign
@property (nonatomic,readwrite, readonly) int height;//readwrite和readonly是一组,只读,和可读可写的内容是相互冲突的只可以选择一个

@property (nonatomic,retain, setter=setMyDog) Dog *dog;//一般不要改setter方法,并且set方法名还有:冒号
@end

@implementation Person
- (void)dealloc
{
    [_car release];
    //[_age release];
    //[_height release];
    [_dog release];
    [super dealloc];
}
@end

No.3 autorelease使用

// 假设有个Person类
// 请找出不合理或者错误的地方
int main()
{
    @autoreleasepool
    {
        Person *p = [[[Person alloc] init] release];
        
        Person *p1 = [[[Person alloc] init] autorelease];
        
        [p1 release];//自动释放池中不用写release
        //[p release];
        
        Person *p2 = [[[[Person alloc] init] autorelease] autorelease];// 多一个autorelease
        
    }
    return0;
}

No.4 autorelease使用

// 假设有个Person类,有个@property (nonatomic, assign) int age;
// 请找出不合理或者错误的地方
int main()
{
    Person *p = nil;
    @autoreleasepool
    {
        p = [[Person alloc] init];
        
        @autoreleasepool
        {
            [p autorelease];
        }
        
        [p setAge:10];//  野指针
    }
    return0;
}

野指针指向一个已删除的对象或未申请访问受限内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。

No.5 请解释以下keywords的区别: assign vs weak, __block vs __weak

assign 适用于基本数据类型, weak适用于NSObject对象,并且是个弱引用。
block是用来修饰一个变量的,这个变量可以在block中被修改(ARC下)。使用block修饰的变量,在block代码块中会被retain(ARC下,MRC下不会)。
使用weak修饰的变量不会在block代码块中被retain。在ARC下,为了避免循环引用,使用weak typeof(self)weakSelf = self;

No.6 __block在arc和非arc下含义一样吗?

是不一样的。
在ARC下,__blcok修饰的变量,在block代码块中会被retain。在MRC下,__blcok修饰的变量,在block代码块中不会被retain。
与之相反的是__weak,__unsafe_unretained. (__weak修饰的变量在release后,此pointer会自动设置为nil)
为了解决循环引用

__blcok MyClass temp = …; //MRC下使用
__weak MyClass temp = …; //ARC下使用,iOS5.0以上的版本
__unsafe_unretained MyClass temp = …; //ARC下,且IOS4.x以后版本

No.6 什么是arc?(arc是为了解决什么问题诞生的?)

首先解释ARC: automatic reference counting自动引用计数。 ARC几个要点: 在对象被创建时 retain count +1,在对象被release时 retain count -1.当retain count 为0 时,销毁对象。 程序中加入autoreleasepool的对象会由系统自动加上autorelease方法,如果该对象引用计数为0,则销毁。 那么ARC是为了解决什么问题诞生的呢?这个得追溯到MRC手动内存管理时代说起。 MRC下内存管理的缺点: 1.当我们要释放一个堆内存时,首先要确定指向这个堆空间的指针都被release了。(避免提前释放) 2.释放指针指向的堆空间,首先要确定哪些指针指向同一个堆,这些指针只能释放一次。(MRC下即谁创建,谁释放,避免重复释放) 3.模块化操作时,对象可能被多个模块创建和使用,不能确定最后由谁去释放。 4.多线程操作时,不确定哪个线程最后使用完毕

No.7 使用nonatomic一定是线程安全的吗?()

atomic:线程安全,需要消耗大量系统资源来为属性加锁
nonatomic:非线程安全,适合内存较小的移动设备

No.8 描述一个你遇到过的retain cycle例子

block中的循环引用:一个viewController

@property (nonatomic,strong)HttpRequestHandler *handler;
@property (nonatomic,strong)NSData *data;

_handler = [httpRequestHandler sharedManager];    
 [_handler  downloadData:^(id responseData){         _data = responseData;     }];

//self 拥有_handler, _handler 拥有block, block拥有self(因为使用了self的_data属性,block会copy 一份self) 
//解决方法:
 __weak typedof(self)weakSelf = self    
 [_handler downloadData:^(id responseData){         weakSelf.data = responseData;     }];
//如果是倒霉催的项目还需要支持iOS4.3,就用__unsafe_unretained替代__weak。
//如果是non-ARC环境下就将__weak替换为__block即可。
non-ARC情况下,__block变量的含义是在Block中引入一个新的结构体成员变量指向这个__block变量,那么__block typeof(self) weakSelf = self。
就表示Block别再对self对象retain啦,这就打破了循环引用。

图解


block循环引用.png

No.9 autorelease

// 假设有个Person类,请问p1、p2、p3、p4指向的对象分别在第几行代码后会销毁
int main()
{
    Person *p1 = nil;
    
    @autoreleasepool
    {
        p1 = [[Person alloc] init];
    }
    
    @autoreleasepool
    {
        [p1 autorelease];//p1
        
        Person *p2 = [[[Person alloc] init] autorelease];//p2
        
        Person *p3 = [[Person alloc] init];
        
        @autoreleasepool
        {
            NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
            
            [p3 autorelease];//p3
            
            Person *p4 = [[Person alloc] init];
            
            [pool release];
            
            [p4 autorelease];//p4
        }       //p4   p3   释放
    }     //    p2   p1     释放
    
    
    return 0;
}

No.10 block一般用那个关键字修饰,为什么?

block一般使用copy关键之进行修饰,block使用copy是从MRC遗留下来的“传统”,在MRC中,方法内容的block是在栈区的,使用copy可以把它放到堆区。但在ARC中写不写都行:编译器自动对block进行了copy操作。

No.11 用@property声明的NSString(或NSArray,NSDictionary)经常使用copy关键字,为什么?如果改用strong关键字,可能造成什么问题?

答:用@property声明 NSString、NSArray、NSDictionary 经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。

如果我们使用是strong,那么这个属性就有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性。

copy此特质所表达的所属关系与strong类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为NSString时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个NSMutableString类的实例。这个类是NSString的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。

No.12 runloop、autorelease pool以及线程之间的关系。、

每个线程(包含主线程)都有一个Runloop。对于每一个Runloop,系统会隐式创建一个Autorelease pool,这样所有的release pool会构成一个像callstack一样的一个栈式结构,在每一个Runloop结束时,当前栈顶的Autorelease pool会被销毁,这样这个pool里的每个Object会被release。

No.13 分别写一个setter方法用于完成@property (nonatomic,retain)NSString *name和@property (nonatomic,copy) NSString *name

retain属性的setter方法是保留新值并释放旧值,然后更新实例变量,令其指向新值。顺序很重要。假如还未保留新值就先把旧值释放了,而且两个值又指向同一个对象,先执行的release操作就可能导致系统将此对象永久回收。

-(void)setName:(NSString *)name
{
    [name retain];
    [_name release];
    _name = name;
}
-(void)setName:(NSString *)name
{
     
    [_name release];
    _name = [name copy];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,146评论 30 470
  • 内存管理 ARC处理原理 ARC是Objective-C编译器的特性,而不是运行时特性或者垃圾回收机制,ARC所做...
    b485c88ab697阅读 11,205评论 3 47
  • 多线程、特别是NSOperation 和 GCD 的内部原理。运行时机制的原理和运用场景。SDWebImage的原...
    LZM轮回阅读 2,007评论 0 12
  • 史上最全的iOS面试题及答案 iOS面试小贴士———————————————回答好下面的足够了----------...
    Style_伟阅读 2,356评论 0 35
  • 1.OC里用到集合类是什么? 基本类型为:NSArray,NSSet以及NSDictionary 可变类型为:NS...
    轻皱眉头浅忧思阅读 1,378评论 0 3