美文网首页iOS面试iOS学习开发面试
iOS开发面试梳理(三)

iOS开发面试梳理(三)

作者: 程序员_秃头怪 | 来源:发表于2019-07-13 16:42 被阅读23次
    一、UIViewController的完整生命周期
    -[ViewController initWithNibName:bundle:];
    -[ViewController init];
    -[ViewController loadView];
    -[ViewController viewDidLoad];
    -[ViewController viewWillAppear:];
    -[ViewController viewDidAppear:];
    -[ViewController viewWillDisappear:];
    -[ViewController viewDidDisappear:];
    
    
    二、深拷贝和浅拷贝
    • 如果对象有个指针型成员变量指向内存中的某个资源,那么如何复制这个对象呢?你会只是复制指针的值传给副本的新对象吗?指针只是存储内存中资源地址的占位符。在复制操作中,如果只是将指针复制给新对象,那么底层的资源实际上仍然由两个实例在共享。
    • 浅复制:两个实例的指针仍指向内存中的同一资源,只复制指针值而不是实际资源;

    • 深复制:不仅复制指针值,还复制指向指针所指向的资源。如下图:

    三、对沙盒的理解

    每个iOS应用都被限制在“沙盒”中,沙盒相当于一个加了仅主人可见权限的文件夹,及时在应用程序安装过程中,系统为每个单独的应用程序生成它的主目录和一些关键的子目录。苹果对沙盒有几条限制:

    1\. 应用程序在自己的沙盒中运作,但是不能访问任何其他应用程序的沙盒;
    2\. 应用之间不能共享数据,沙盒里的文件不能被复制到其他 应用程序的文件夹中,也不能把其他应用文件夹复制到沙盒中;
    3\. 苹果禁止任何读写沙盒以外的文件,禁止应用程序将内容写到沙盒以外的文件夹中;
    4\. 沙盒目录里有三个文件夹:Documents——存储应用程序的数据文件,
       存储用户数据或其他定期备份的信息;Library下有两个文件夹,Caches存储应用程序再次启动所需的信息,
       Preferences包含应用程序的偏好设置文件,不可在这更改偏好设置;
       temp存放临时文件即应用程序再次启动不需要的文件。
    
    
    • 获取沙盒根目录的方法,有几种方法:用NSHomeDirectory获取。

    • 获取Document路径:
      NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES).

    四、ViewController 的 loadView,、viewDidLoad,、viewDidUnload 分别是在什么时候调用的?
    • viewDidLoad在view从nib文件初始化时调用,loadView在controller的view为nil时调用。

    • 此方法在编程实现view时调用,view控制器默认会注册memory warning notification,当view controller的任何view没有用的时候,viewDidUnload会被调用,在这里实现将retainview release,如果是retainIBOutlet view 属性则不要在这里release,IBOutlet会负责release

    五、@synthesize、@dynamic的理解
    • @synthesize是系统自动生成getter和setter属性声明;@synthesize的意思是,除非开发人员已经做了,否则由编译器生成相应的代码,以满足属性声明;

    • @dynamic是开发者自已提供相应的属性声明,@dynamic意思是由开发人员提供相应的代码:对于只读属性需要提供setter,对于读写属性需要提供 settergetter。查阅了一些资料确定@dynamic的意思是告诉编译器,属性的获取与赋值方法由用户自己实现, 不自动生成。

    六、frame和bounds有什么不同?
    • frame指的是:该view在父view坐标系统中的位置和大小。(参照点是父亲的坐标系统)

    • bounds指的是:该view在本身坐标系统中的位置和大小。(参照点是本身坐标系统)

    七、view的touch事件有哪些?
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; 
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; 
    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; 
    - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
    
    
    八、property属性的修饰符的作用
    • getter=getName、setter=setName:设置setter与getter的方法名;

    • readwrite、readonly:设置可供访问级别;

    • assign:方法直接赋值,不进行任何retain操作,为了解决原类型与环循引用问题;

    • retain:其setter方法对参数进行release旧值再retain新值,所有实现都是这个顺序;

    • copy:其setter方法进行copy操作,与retain处理流程一样,先对旧值release,再copy出新的对象,retainCount为1。这是为了减少对上下文的依赖而引入的机制。

    • nonatomic:非原子性访问,不加同步, 多线程并发访问会提高性能。注意,如果不加此属性,则默认是两个访问方法都为原子型事务访问。

    九、对于Run Loop的理解
    • RunLoop,是多线程的法宝,即一个线程一次只能执行一个任务,执行完任务后就会退出线程。主线程执行完即时任务时会继续等待接收事件而不退出。非主线程通常来说就是为了执行某一任务的,执行完毕就需要归还资源,因此默认是不运行RunLoop的;

    • 每一个线程都有其对应的RunLoop,只是默认只有主线程的RunLoop是启动的,其它子线程的RunLoop默认是不启动的,若要启动则需要手动启动;

    • 在一个单独的线程中,如果需要在处理完某个任务后不退出,继续等待接收事件,则需要启用RunLoop;

    • NSRunLoop提供了一个添加NSTimer的方法,可以指定Mode,如果要让任何情况下都回调,则需要设置Mode为Common模式;

    • 实质上,对于子线程的runloop默认是不存在的,因为苹果采用了懒加载的方式。如果我们没有手动调用[NSRunLoop currentRunLoop]的话,就不会去查询是否存在当前线程的RunLoop,也就不会去加载,更不会创建。

    十、SQLite中常用的SQL语句
    • 创建表:creat table 表名 (字段名 字段数据类型 是否为主键, 字段名 字段数据类型, 字段名 字段数据类型...);

    • 增: insert into 表名 (字段1, 字段2...) values (值1, 值2...);

    • : delete from 表名 where 字段 = 值;

    十一、XIB与Storyboards的优缺点

    优点:

    • XIB:在编译前就提供了可视化界面,可以直接拖控件,也可以直接给控件添加约束,更直观一些,而且类文件中就少了创建控件的代码,确实简化不少,通常每个XIB对应一个类。

    • Storyboard:在编译前提供了可视化界面,可拖控件,可加约束,在开发时比较直观,而且一个storyboard可以有很多的界面,每个界面对应一个类文件,通过storybard,可以直观地看出整个App的结构。

    缺点:

    • XIB:需求变动时,需要修改XIB很大,有时候甚至需要重新添加约束,导致开发周期变长。XIB载入相比纯代码自然要慢一些。对于比较复杂逻辑控制不同状态下显示不同内容时,使用XIB是比较困难的。当多人团队或者多团队开发时,如果XIB文件被发动,极易导致冲突,而且解决冲突相对要困难很多。
    • Storyboard:需求变动时,需要修改storyboard上对应的界面的约束,与XIB一样可能要重新添加约束,或者添加约束会造成大量的冲突,尤其是多团队开发。对于复杂逻辑控制不同显示内容时,比较困难。当多人团队或者多团队开发时,大家会同时修改一个storyboard,导致大量冲突,解决起来相当困难。
    十二、将字符串“2015-04-10”格式化日期转为NSDate类型
    NSString *timeStr = @"2015-04-10";
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy-MM-dd";
    formatter.timeZone = [NSTimeZone defaultTimeZone];
    NSDate *date = [formatter dateFromString:timeStr];
    // 2015-04-09 16:00:00 +0000
    NSLog(@"%@", date);
    
    
    十三、UIImageView添加圆角
    • 最直接的方法就是使用如下属性设置
    imgView.layer.cornerRadius = 10;
    // 这一行代码是很消耗性能的
    imgView.clipsToBounds = YES;
    
    

    这是离屏渲染(off-screen-rendering),消耗性能的

    • 给UIImage添加生成圆角图片的扩展API:这是on-screen-rendering
    - (UIImage *)imageWithCornerRadius:(CGFloat)radius {
        CGRect rect = (CGRect){0.f, 0.f, self.size};
    
        UIGraphicsBeginImageContextWithOptions(self.size, NO, UIScreen.mainScreen.scale);
        CGContextAddPath(UIGraphicsGetCurrentContext(), 
        [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:radius].CGPath);
        CGContextClip(UIGraphicsGetCurrentContext());
    
        [self drawInRect:rect];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return image;
    }
    

    推荐一个iOS技术交流群:923910776!群内有最近整理出来的面试题,以及一些书籍学习资料!也是为了给大部分还在做iOS开发的朋友一个交流圈子!

    相关文章

      网友评论

        本文标题:iOS开发面试梳理(三)

        本文链接:https://www.haomeiwen.com/subject/xiqmkctx.html