程序猿iOS面试资料iOS Developer

iOS | 面试知识整理 - OC基础 (一)

2019-07-29  本文已影响0人  Leon_520

前言:

最近公司项目不怎么忙, 闲暇时间把iOS 在面试中可能会遇到的问题整理了一番, 一部分题目是自己面试遇到的,一部分题目则是网上收录的, 方便自己巩固复习, 也分享给大家! 知识点比较多,比较杂,这里做了分类,下面是分类链接地址;

面试知识点整理 - 目录:
iOS | 面试知识整理 - OC基础 (一)
iOS | 面试知识整理 - OC基础 (二)
iOS | 面试知识整理 - OC基础 (三)
iOS | 面试知识整理 - UI 相 关 (四)
iOS | 面试知识整理 - 内存管理 (五)
iOS | 面试知识整理 - 多 线 程 (六)
iOS | 面试知识整理 - 网络相关 (七)
iOS | 面试知识整理 - 数据持久化 (八)
iOS | 面试知识整理 - Swift 基础 (九)

iOS | 面试知识整理 - OC基础 (一)

1. #include、#import、@class的区别?

2. id 和 instancetype的区别?

3. New 作用是什么?

  1. 向计算机(堆区)申请内存空间;
  2. 给实例变量初始化;
  3. 返回所申请空间的首地址;

4.OC实例变量的修饰符? 及作用范围?

@puplic

 1.可以在其他类中访问被@public修饰的成员变量
 2.也可以在本类中访问被@public修饰的成员变量
 3.可以在子类中访问父类中被@public修饰的成员变量

@private

1.不可可以在其他类中访问被@private修饰的成员变量
2.也可以在本类中访问被@private修饰的成员变量
3.不可以在子类中访问父类中被@private修饰的成员变量

@protected (默认情况下所有的实例变量都是protected)

1.不可可以在其他类中访问被@protected修饰的成员变量
2.也可以在本类中访问被@protected修饰的成员变量
3.可以在子类中访问父类中被@protected修饰的成员变量

@package

介于public和private之间的,如果是在其他包中访问就是private,在当前代码中访问就是public.

5. @proprety的作用

@property = ivar + getter + setter;
  1. 在.h文件中帮我们自动生成getset方法声明
  2. 在.m文件中帮我们生成私有的实例变量(前提是没有在.h文件中没有手动生成)
  3. 在.m文件中帮我们是实现get和set方法的实现

6. @proprety 参数说明?

7 NSObject和id的区别?

8. id类型, nil , Nil ,NULL和NSNULL的区别?

9. atomic和nonatomic区别,以及作用?

atomicnonatom的主要区别就是系统自动生成的getter/setter方法不一样

atomic不是线程安全的

10. 什么情况使用 weak 关键字,相比 assign 有 什么不同?

weak 和 assign 的不同点

11. 代理使用 weak 还是 assign

12. ARC 下,不显式指定任何属性关键字时,默认 的关键字都有哪些?

13. 怎么用 copy 关键字?

14. 如何让自定义类可以用 copy 修饰符?如何重写带 copy 关键字的 setter?

若想令自己所写的对象具有拷贝功能,则需实现 NSCopying 协议。如果自定义的对象分为可变版本与不可变版本,那么就要同时实现 NSCopyiog 与 NSMutableCopying 协议

// 实现不可变版本拷贝
- (id)copyWithZone:(NSZone *)zone; 
// 实现可变版本拷贝
- (id)mutableCopyWithZone:(NSZone *)zone;
// 重写带 copy 关键字的 setter
- (void)setName:(NSString *)name {
    _name = [name copy];
}

15. weak 属性需要在 dealloc 中置 nil 么

16.说一下OC的反射机制;

17.手写单例

方式一: 不是线程安全的,如果多线程需要加锁

static ClassName *_instance;
+ (instancetype)sharedInstance{
   @synchronized (self) {
       if(!_instance)   {
           _instance = [self alloc]init];
       }
    }
    return _instance;
} 

方式二: 注意多线程问题 GCDdispatch_once 默认是线程安全的

  static ClassName *_instance;
    + (instancetype)sharedInstance{
        static dispatch_one_t oneToken;
        dispatch_once(&onetoken,^{
           _instance = [self alloc]init];
        });
        return _instance;
    }
    
    + (instancetype)allocWithZone:(NSZone *) zone{
      static dispatch_t onetoken;
      dispatch_once(&oncetoken ^{
         _instance = [super allocwithzone:zone];
      })
      retun _instance
    }

18. 什么是僵尸对象?

19.野指针

比如:

NSObject *obj = [NSObject new];
[obj release]; // obj 指向的内存地址已经释放了,
obj 如果再去访问的话就是野指针错误了.
野指针错误形式在Xcode中通常表现为:Thread 1:EXC_BAD_ACCESS,因为你访问了一块已经不属于你的内存。

20. 什么是内存泄露?

21.数组copy后里面的元素会复制一份新的吗

22. 如下代码,会有什么问题吗?

@property (copy, nonatomic) NSMutableArray * array

使用 copy 修饰,会生成不可变数组,在添加删除数组元素时候会崩溃

23. OC中的NSInteger 和int 有什么区别

24. @synthesize 和 @dynamic 分别有什么作用

25.NSMutableDictionary 中使用setValueForKey 和 setObjectForKey有什么区别?

26.列举出延迟调用的几种方法?

[self performSelector:@selector(Delay) withObject:nil afterDelay:3.0f];
[NSTimer scheduledTimerWithTimeInterval:3.0f target:self selector:@selector(Delay) userInfo:nil repeats:NO];
[NSThread sleepForTimeInterval:3.0f];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
        [self Delay];
    });
- (void)Delay {
 NSLog(@"执行"); 
}

27. NSCache 和NSDictionary 区别?

  1. NSCache可以提供自动删减缓存功能,而且保证线程安全,与字典不同,不会拷贝键。
  2. NSCache可以设置缓存上限,限制对象个数和总缓存开销。定义了删除缓存对象的时机。这个机制只对NSCache起到指导作用,不会一定执行。
  3. NSPurgeableData搭配NSCache使用,可以自动清除数据。
  4. 只有那种“重新计算很费劲”的数据才值得放入缓存。

28.NSArray 和 NSSet区别

29.声明一个函数,传入值是一个输入输出参数都是 int的 block 函数

- (void)test_Function:(int(^)(int num)) block{}

30.面向对象和面向过程的区别?

31.对象方法和类方法的区别?

32. 什么是面向过程?(POP--Procedure Oriented Programming)

33. 什么是面向对象?(OOP--Object Oriented Programming)

  1. 封装
    隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性。
  2. 继承
    提高代码复用性;建立了类之间的关系;子类可以拥有父类的所有成员变量的方法;继承是多态的前提。
  3. 多态
    父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。

34. 什么是多态?

35. 什么是分类?

36.什么是协议?

37.正式协议&非正式协议?

38.如何实现多继承?

  1. 类别
  2. 协议
  3. 消息转发 (后面会详细讲述)

39.为什么说OC是一门动态语言?

OC的动态特性可从三方面:

40.动态绑定?

41. cocoa 和 cocoa touch是什么?区别?

42. cocoa touch底层技术架构?

cocoa touch底层技术架构 主要分为4层:

43. 什么是谓词?

谓词(NSPredicate)是OC针对数据集合的一种逻辑帅选条件,类似一个过滤器,简单实实用代码如下:

Person * p1 = [Person personWithName:@"alex" Age:20];
Person * p2 = [Person personWithName:@"alex1" Age:30];
Person * p3 = [Person personWithName:@"alex2" Age:10];
Person * p4 = [Person personWithName:@"alex3" Age:40];
Person * p5 = [Person personWithName:@"alex4" Age:80];
    
NSArray * persons = @[p1, p2, p3, p4, p5];
//定义谓词对象,谓词对象中包含了过滤条件
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"age < 30"];
//使用谓词条件过滤数组中的元素,过滤之后返回查询的结果
NSArray *array = [persons filteredArrayUsingPredicate:predicate];

44. 什么是类工厂方法?

类工厂方法就是用来快速创建对象的类方法, 他可以直接返回一个初始化好的对象,具备以下特征:

  1. 一定是类方法
  2. 返回值需要是 id/instancetype 类型
  3. 规范的方法名说说明类工厂方法返回的是一个什么对象,一般以类名首字母小写开始;

比如系统 UIButton 的buttonWithType 就是一个类工厂方法:

// 类工厂方法
+ (instancetype)buttonWithType:(UIButtonType)buttonType;
// 使用
+ UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom];

45. 什么是糖衣语法?

糖衣语法又叫做语法糖语法盐,是指在计算机语言中添加某种语法,这种语法对语言的功能没有影响,但更方便程序员使用,增加程序的可读性,减少代码出错机会

OC中的字面量,其实就是语法糖

NSNumber * number = @1;
NSArray * array = @[@1, @2, @3];
NSDictionary * dict = @{@"key":@"value"};
NSNumber * num1 = array[0];
NSString * value = dict[@"key"];

46.Svn 和 Git 区别

47.OC中有二维数组吗? 如何实现?

OC中没有二维数组, 可以通过一维数组嵌套来实现二维数组;

// 字面量定义
NSArray * array = @[
                    @[@1,@2,@3,@4,@5],
                    @[@11,@12,@13,@14,@15],
                    @[@21,@22,@23,@24,@25],
                    @[@31,@32,@33,@34,@35],
                    @[@41,@42,@43,@44,@45],
                    ];

// 访问
NSLog(@"%@",array[1][1]);

48.CocoaPods理解

CocoaPods 是一个 objc 的依赖管理工具,而其本身是利用 ruby 的依赖管理 gem 进行构建的

49. --verbose 和 --no-repo-update有什么用?

50. KVC中的集合运算符

  1. 简单集合运算符:@avg、@sum、@max、@min、@count (只能用在集合对象中,对象属性必须为数字类型)
  2. 对象操作符:
    @unionOfObjects:返回指定属性的值的数组,不去重
    @distinctUnionOfObjects:返回指定属性去重后的值的数组
  3. 数组 / 集体操作符:跟对象操作符很相似,只不过是在NSArray和NSSet所组成的集合中工作的。@unionOfArrays:返回一个数组,值由各个子数组的元素组成,不去重 @distinctUnionOfArrays:返回一个数组,值由各个子数组的元素组成,去重 @distinctUnionOfSets:和@distinctUnionOfArrays差不多, 只是它期望的是一个包含着NSSet对象的NSSet,并且会返回一个NSSet对象。因为集合不能有重复的值,所以只有distinct操作。

51.简要说明const,宏,static,extern区分以及使用?

const

const常量修饰符,经常使用的字符串常量,一般是抽成宏,但是苹果不推荐我们抽成宏,推荐我们使用const常量。

- const 作用:限制类型
- 使用const修饰基本变量, 两种写法效果一致 , b都是只读变量
  const int b = 5; 
  int const b = 5;   
- 使用const修饰指针变量的变量 
  第一种: const int *p = &a 和 int const *q = &a; 效果一致,*p 的值不能改,p 的指向可以改; 
  第二种: int * const p = &a;  表示 p 的指向不能改,*p 的值可以改
  第三种: 
  const int * const p = &a; *p 值和 p 的指向都不能改
  
  const 在*左边, 指向可变, 值不可变
  const 在*的右边, 指向不可变, 值可变
  const 在*的两边, 都不可变

* 基本概念:宏是一种批量处理的称谓。一般说来,宏是一种规则或模式,或称语法替换 ,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串)。这种替换在预编译时进行,称作宏展开。编译器会在编译前扫描代码,如果遇到我们已经定义好的宏那么就会进行代码替换,宏只会在内存中copy一份,然后全局替换,宏一般分为对象宏和函数宏。 宏的弊端:如果代码中大量的使用宏会使预编译时间变长。

const与宏的区别?

* 编译检查 宏没有编译检查,const有编译检查;
* 宏的好处 定义函数,方法 const不可以;
* 宏的坏处 大量使用宏,会导致预编译时间过长

static

* 修饰局部变量: 被static修饰局部变量,延长生命周期,跟整个应用程序有关,程序结束才会销毁,被 static 修饰局部变量,只会分配一次内存
* 修饰全局变量: 被static修饰全局变量,作用域会修改,也就是只能在当前文件下使用

extern

声明外部全局变量(只能用于声明,不能用于定义)

常用用法(.h结合extern联合使用)
如果在.h文件中声明了extern全局变量,那么在同一个类中的.m文件对全局变量的赋值必须是:数据类型+变量名(与声明一致)=XXXX结构。并且在调用的时候,必须导入.h文件。代码如下:

.h
@interface ExternModel : NSObject
extern NSString *lhString;
@end 
.m     
@implementation ExternModel
NSString *lhString=@"hello";
@end

调用的时候:例如:在viewController.m中调用,则可以引入:ExternModel.h,否则无法识别全局变量。当然也可以通过不导入头文件的方式进行调用(通过extern调用)。

52.编译型和解释型的区别?

53.动态语言和静态语言?

54.什么是指针常量和常量指针?

55. 指针函数和函数指针

指针函数

// 指针函数
int *sum(int a, int b){
    int result = a + b;
    int *c = &result;
    return c;
}
int *p = sum(10, 20);
printf("sum:%d\n", *p);

函数指针

// 函数指针
int max(int a, int b){
    return (a > b)?a:b;
}
int (*p)(int, int) = max;
int result = p(10, 20);
printf("result:%d\n", result);

56.写一个标准的宏MAX,这个宏输入2个参数,返回最大一个

#define Max(a,b) a>b?a:b

57.自定义宏 #define MIN(A,B) A<B?A:B 代码运行结果?

float a = 1;
float b = MIN(a++,1.5);
问 a= ? b = ?
答案: a = 3; b = 2
a++ 会后执行, a++在表达式出现了2次,得3,  a++<1.5,返回a++,得2

// 扩展
float a = 1;
float b = [self getMix:a++ b:1.5];
- (CGFloat)getMix:(CGFloat ) a b:(CGFloat)b{
   return a>b?a:b;
}
运行 a = 2; b =1;

下一篇入口:

iOS | 面试知识整理 - OC基础 (二)

上一篇下一篇

猜你喜欢

热点阅读