iOS面试题(答案)

来源:互联网 发布:怎么样增加淘宝粉丝 编辑:程序博客网 时间:2024/04/27 22:35

1、 简述OC中内存管理机制。与retain配对使用的方法是dealloc还是release,为什么?需要与alloc配对使用的方法是dealloc还是release,为什么?readwritereadonlyassignretaincopynonatomic atomicstrongweak属性的作用? 
OC使用了一种叫做引用计数的机制来管理对象,如果对一个对象使用了alloc[Mutable]copyretain,那么你必须使用相应的realease或者autorelease。也可以理解为自己生成的对象,自己持有。非自己生成的对象,自己也能持有。不在需要自己持有的对象时释放。非自己持有的对象无法释放。生成并持有对象<alloc,new,copy,mutableCopy>,持有对象<retain>,释放对象<release>,废弃对象<dealloc>readwrite(默认):可读可写,表示既有getter方法,也有setter方法。readonly:表示只有getter方法,没有setter方法。nonatomic:不考虑线程安全。atomic(默认):线程操作安全。strong(默认):ARC下和MRCretain一样,weakARC下):和(MRC)assign类似,区别是当weak指向的内存释放掉后自动置为nil,防止野指针。

unsafe_unretained声明一个若引用,但不会自动置为nil,可能会出现野指针。

线程安全下的settergetter方法:

- (NSString *value{

@synchronizedself{

return [[_value retain] autorelease];

}

}

- (void)setValue:(NSString *)aValue{

@synchronized(self){

[aValue retain];

[_value release];

_value = aValue;

}

}

2、类变量的@protected ,@private,@public,@package声明各有什么含义?
上面的几个声明表明的时类成员的作用域,@private作用范围只能在自身类(外界既不可访问,又不能继承);@protected作用范围在自身类和子类,如果什么都不加修饰,默认是@protected(外界不可访问,但是可以继承);@public作用范围最大,可以在任何地方被访问(外界即可访问,又可以继承);@package作用范围在某个框架内

3、 谈谈你对多线程开发的理解?ios中有几种实现多线程的方法?
好处:
(1)使用线程可以把程序中占据时间长的任务放到后台去处理,如图片、视频的下载
(2)发挥多核处理器的优势,并发执行让系统运行的更快、更流畅,用户体验更好
缺点:
(1)大量的线程降低代码的可读性,
(2)更多的线程需要更多的内存空间
(3)当多个线程对同一个资源出现争夺的时候要注意线程安全的问题。
iOS有三种多线程编程的技术:
(1)NSThread(两种创建方式)
[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
NSThread *myThread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:nil];

[myThread start];
(2)NSOperationQueue

NSOperationQueue *oprationQueue = [[NSOperationQueue alloc] init];

oprationQueue addOperationWithBlock:^{

//这个block语句块在子线程中执行

}

http://alloc.sinaapp.com/wp/?p=237

(3)Grand Central Dispatch (GCD)

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 耗时的操作

    dispatch_async(dispatch_get_main_queue(), ^{

        // 更新界面

    });

});

http://blog.csdn.net/totogo2010/article/details/8016129

 

PS:不显示的创建线程的方法:
NSObject的类方法  performSelectorInBackground:withObject: 创建一个线程:
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];

4、 iOS本地数据存储都有哪几种方式?iOS如何实现复杂对象的存储?

(1) NSKeyedArchiver(归档)采用归档的形式来保存数据,该数据对象需要遵守NSCoding协议,并且该对象对应的类必须提供encodeWithCoder:initWithCoder:方法

(2) NSUserDefaults:用来保存应用程序设置和属性、用户保存的数据。用户再次打开程序或开机后这些数据仍然存在。NSUserDefaults可以存储的数据类型包括:NSDataNSStringNSNumberNSDateNSArrayNSDictionary

(3) Write写入方式:永久保存在磁盘中。

(4) SQLiteFMDBCoreData

NSCoding + NSKeyedArchiver实现复杂对象的存储。

5、 iOS的动态性
iOS的动态性来自三个方面:动态类型、动态绑定、动态载入、SEL类型 

(1)动态类型<弱类型>id):在代码的运行阶段判断代码的类型,使用id类型可以让应用在“运行时”使用任何类型来替换。动态类型让程序更加灵活,但是会使数据的统一性降低和代码的可读性。我们常用静态类型<强类型>(如NSString,使用静态类型编译器可以完全分析你的代码,这让代码的性能和可预知性更高。
(2)动态绑定:让代码在运行时判断需要调用什么方法,而不是在编译时。 动态类型和动态绑定使得选择哪个接收者已经调用什么方法都放到运行时去完成。    

(3)动态载入:应用程序可以根据需要加载可执行代码以及资源,而不是在启动时就加载所有资源。

(4)SEL类型 iOS在编译的时候会根据方法的名字(包括参数序列),生成一个用来区分这个方法的唯一的ID,这个IDSEL类型的,SEL的本质就是类方法的编号[函数地址]。(类似C语言里面的函数指针,但是OC的类不能直接使用函数指针,这样只能做一个@selector语法来取。注意:@selector是查找当前类(含子类)的方法。

6、写出方法获取ios内存使用情况。
// 获取当前设备可用内存及所占内存的头文件

#import <sys/sysctl.h>

#import <mach/mach.h>

// 获取当前设备可用内存(单位:MB

- (double)availableMemory

{

  vm_statistics_data_t vmStats;

  mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;

  kern_return_t kernReturn = host_statistics(mach_host_self(), 

                                             HOST_VM_INFO

                                             (host_info_t)&vmStats, 

                                             &infoCount);

  

  if (kernReturn != KERN_SUCCESS) {

    return NSNotFound;

  }

  

  return ((vm_page_size *vmStats.free_count) / 1024.0) / 1024.0;

}

 

// 获取当前任务所占用的内存(单位:MB

- (double)usedMemory

{

  task_basic_info_data_t taskInfo;

  mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;

  kern_return_t kernReturn = task_info(mach_task_self(), 

                                       TASK_BASIC_INFO

                                       (task_info_t)&taskInfo, 

                                       &infoCount);

 

  if (kernReturn != KERN_SUCCESS

      ) {

    return NSNotFound;

  }

  

  return taskInfo.resident_size / 1024.0 / 1024.0;}

7、什么是安全释放?

在对象release之后把指针置为nil,但不是绝对的安全释放,只是理论上。

8、 RunLoop是什么?
一个RunLoop就是一个时间处理的循环,用来不停的调度工作以及处理输入时间。使用runloop的目的是让你的线程在有工作的时候忙于工作,而没工作的时候处于休眠状态。runloop的设计是为了减少cpu无谓的空转。

9、什么是序列化和反序列化,可以用来做什么?如何在OC中实现复杂对象的存储?
如果你需要存储一个复杂的对象的话,经常要以二进制的方法序列化这个对象,这个过程叫Archiving。如果一个对象需要进行序列化,那么需要遵循NScoding协议,主要有两个方法:
-(id)initWithCoder:(NSCoder*)coder;//coder中读取数据,保存到相应变量中,即反序列化数据。
-(void)encodeWithCoder:(NSCoder*)coder;//读取实例变量,并把这些数据写到coder中去,即序列化数据。

10、 iphone os有没有垃圾回收机制?简单阐述一下OC内存管理。
iphone os没有垃圾回收机制。
垃圾回收机制用于在空闲时间以不定时的方式动态的回收无任何引用的对象占据的内存空间。





0 0
原创粉丝点击