你能用到的iOS面试题(一)

题目来源自这里,笔者对知识类问题和经验类问题做了解答,答案有遗漏的地方希望大家能补充,这是你能用到的面试题(二)

什么是响应链,它是怎么工作的?

这个问题笔者写过一篇博客,里面有对这个问题的详细解释

如何访问并修改一个类的私有属性?

  • 有两种方法可以访问私有属性,一种是通过KVC获取,一种是通过runtime访问并修改私有属性
  • 创建一个Father类,声明一个私有属性name,并重写description打印name的值,在另外一个类中通过runtime来获取并修改Father中的属性
@interface Father ()
@property (nonatomic, copy) NSString *name;
@end
@implementation Father

- (NSString *)description
{
    return [NSString stringWithFormat:@"name:%@",_name];
}

@implementation ViewController

- (void)viewDidLoad {

    [super viewDidLoad];

    Father *father = [Father new];  
    // count记录变量的数量IVar是runtime声明的一个宏
    unsigned int count = 0;
    // 获取类的所有属性变量
    Ivar *menbers = class_copyIvarList([Father class], &count);
    
    for (int i = 0; i < count; i++) {
        Ivar ivar = menbers[i];
        // 将IVar变量转化为字符串,这里获得了属性名
        const char *memberName = ivar_getName(ivar);
        NSLog(@"%s",memberName);
        
        Ivar m_name = menbers[0];
        // 修改属性值
        object_setIvar(father, m_name, @"zhangsan");
        // 打印后发现Father中name的值变为zhangsan
        NSLog(@"%@",[father description]);
    }

}

iOS Extension 是什么?能列举几个常用的 Extension 么?

  • Extension是扩展,没有分类名字,是一种特殊的分类,类扩展可以扩展属性,成员变量和方法
  • 常用的扩展是在.m文件中声明私有属性和方法,这里不知道还哪些,请大家补充

如何把一个包含自定义对象的数组序列化到磁盘?

  • 自定义对象只需要实现NSCoding协议即可
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    User *user = [User new];
    Account *account = [Account new];
    NSArray *userArray = @[user, account];
    // 存到磁盘
    NSData * tempArchive = [NSKeyedArchiver archivedDataWithRootObject: userArray];
}
// 代理方法
- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        self.user = [aDecoder decodeObjectForKey:@"user"];
        self.account = [aDecoder decodeObjectForKey:@"account"];
    }
    return self;
}
// 代理方法
-(void)encodeWithCoder:(NSCoder *)aCoder{
    [aCoder encodeObject:self.user forKey:@"user"];
    [aCoder encodeObject:self.account forKey:@"account"];
}

Apple Pay 是什么?它的大概工作流程是怎样的?

这个笔者也没有详细了解过,大家可以百度谷歌一下具体的

iOS 的沙盒目录结构是怎样的? App Bundle 里面都有什么?

1.沙盒结构

  • Application:存放程序源文件,上架前经过数字签名,上架后不可修改
  • Documents:常用目录,iCloud备份目录,存放数据,这里不能存缓存文件,否则上架不被通过
  • Library
    • Caches:存放体积大又不需要备份的数据,SDWebImage缓存路径就是这个
    • Preference:设置目录,iCloud会备份设置信息
  • tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能

2.App Bundle 里面有什么

  • Info.plist:此文件包含了应用程序的配置信息.系统依赖此文件以获取应用程序的相关信息
  • 可执行文件:此文件包含应用程序的入口和通过静态连接到应用程序target的代码
  • 资源文件:图片,声音文件一类的
  • 其他:可以嵌入定制的数据资源

iOS 的签名机制大概是怎样的?

假设,我们有一个APP需要发布,为了防止中途篡改APP内容,保证APP的完整性,以及APP是由指定的私钥发的。首先,先将APP内容通过摘要算法,得到摘要,再用私钥对摘要进行加密得到密文,将源文本、密文、和私钥对应的公钥一并发布即可。那么如何验证呢?
验证方首先查看公钥是否是私钥方的,然后用公钥对密文进行解密得到摘要,将APP用同样的摘要算法得到摘要,两个摘要进行比对,如果相等那么一切正常。这个过程只要有一步出问题就视为无效。

iOS 7的多任务添加了哪两个新的 API? 各自的使用场景是什么?

  • 后台获取(Background Fetch):后台获取使用场景是用户打开应用之前就使app有机会执行代码来获取数据,刷新UI。这样在用户打开应用的时候,最新的内容将已然呈现在用户眼前,而省去了所有的加载过程。
  • 推送唤醒(Remote Notifications):使用场景是使设备在接收到远端推送后让系统唤醒设备和我们的后台应用,并先执行一段代码来准备数据和UI,然后再提示用户有推送。这时用户如果解锁设备进入应用后将不会再有任何加载过程,新的内容将直接得到呈现。

UIScrollView 大概是如何实现的,它是如何捕捉、响应手势的?

  • 我对UIScrollView的理解是frame就是他的contentSize,bounds就是他的可视范围,通过改变bounds从而达到让用户误以为在滚动,以下是一个简单的UIScrollView实现

在头文件定义一个contentSize属性

@interface MyScrollView : UIView
@property (nonatomic) CGSize contentSize;
@end
@implementation MyScrollView
- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self == nil) {
        return nil;
    }
    // 添加一个滑动手势
    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGesture:)];
    [self addGestureRecognizer:pan];
    return self;
}

- (void)panGesture:(UIPanGestureRecognizer *)gestureRecognizer{
    // 改变bounds
    CGPoint translation = [gestureRecognizer translationInView:self];
    CGRect bounds = self.bounds;
    
    CGFloat newBoundsOriginX = bounds.origin.x - translation.x;
    CGFloat minBoundsOriginX = 0.0;
    CGFloat maxBoundsOriginX = self.contentSize.width - bounds.size.width;
    bounds.origin.x = fmax(minBoundsOriginX, fmin(newBoundsOriginX, maxBoundsOriginX));
    
    CGFloat newBoundsOriginY = bounds.origin.y - translation.y;
    CGFloat minBoundsOriginY = 0.0;
    CGFloat maxBoundsOriginY = self.contentSize.height - bounds.size.height;
    bounds.origin.y = fmax(minBoundsOriginY, fmin(newBoundsOriginY, maxBoundsOriginY));
    
    self.bounds = bounds;
    [gestureRecognizer setTranslation:CGPointZero inView:self];
}
  • 第二个问题个人理解是解决手势冲突,对自己添加的手势进行捕获和响应
// 让UIScrollView遵守UIGestureRecognizerDelegate协议,实现这个方法,在这里方法里对添加的手势进行处理就可以解决冲突
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer

Objective-C 如何对已有的方法,添加自己的功能代码以实现类似记录日志这样的功能?

  • 这题目主要考察的是runtime如何交换方法

先在分类中添加一个方法,注意不能重写系统方法,会覆盖

+ (NSString *)myLog
{
    // 这里写打印行号,什么方法,哪个类调用等等
}

然后交换方法

// 加载分类到内存的时候调用
+ (void)load
{
    // 获取imageWithName方法地址
    Method description = class_getClassMethod(self, @selector(description));

    // 获取imageWithName方法地址
    Method myLog = class_getClassMethod(self, @selector(myLog));

    // 交换方法地址,相当于交换实现方式
    method_exchangeImplementations(description, myLog);
}

+load 和 +initialize 的区别是什么?

  • +(void)load;
    • 当类对象被引入项目时, runtime 会向每一个类对象发送 load 消息
      load 方法会在每一个类甚至分类被引入时仅调用一次,调用的顺序:父类优先于子类, 子类优先于分类
    • load 方法不会被类自动继承
  • +(void)initialize;
    • 也是在第一次使用这个类的时候会调用这个方法

如何让 Category 支持属性?

  • 使用runtime可以实现

头文件

@interface NSObject (test)
 
@property (nonatomic, copy) NSString *name;
 
@end

.m文件

@implementation NSObject (test)
// 定义关联的key
static const char *key = "name";
- (NSString *)name
{
    // 根据关联的key,获取关联的值。
    return objc_getAssociatedObject(self, key);
}
- (void)setName:(NSString *)name
{
    // 第一个参数:给哪个对象添加关联
    // 第二个参数:关联的key,通过这个key获取
    // 第三个参数:关联的value
    // 第四个参数:关联的策略
    objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

NSOperation 相比于 GCD 有哪些优势?

  • 提供了在 GCD 中不那么容易复制的有用特性。
  • 可以很方便的取消一个NSOperation的执行
  • 可以更容易的添加任务的依赖关系
  • 提供了任务的状态:isExecuteing, isFinished.

strong / weak / unsafe_unretained 的区别?

  • weak只能修饰OC对象,使用weak不会使计数器加1,对象销毁时修饰的对象会指向nil
  • strong等价与retain,能使计数器加1,且不能用来修饰数据类型
  • unsafe_unretained等价与assign,可以用来修饰数据类型和OC对象,但是不会使计数器加1,且对象销毁时也不会将对象指向nil,容易造成野指针错误

如何为 Class 定义一个对外只读对内可读写的属性?

在头文件中将属性定义为readonly,在.m文件中将属性重新定义为readwrite

Objective-C 中,meta-class 指的是什么?

meta-class 是 Class 对象的类,为这个Class类存储类方法,当一个类发送消息时,就去那个类对应的meta-class中查找那个消息,每个Class都有不同的meta-class,所有的meta-class都使用基类的meta-class(假如类继承NSObject,那么他所对应的meta-class也是NSObject)作为他们的类

UIView 和 CALayer 之间的关系?

  • UIView显示在屏幕上归功于CALayer,通过调用drawRect方法来渲染自身的内容,调节CALayer属性可以调整UIView的外观,UIView继承自UIResponder,CALayer不可以响应用户事件
  • UIView是iOS系统中界面元素的基础,所有的界面元素都继承自它。它内部是由Core Animation来实现的,它真正的绘图部分,是由一个叫CALayer(Core Animation Layer)的类来管理。UIView本身,更像是一个CALayer的管理器,访问它的根绘图和坐标有关的属性,如frame,bounds等,实际上内部都是访问它所在CALayer的相关属性
  • UIView有个layer属性,可以返回它的主CALayer实例,UIView有一个layerClass方法,返回主layer所使用的类,UIView的子类,可以通过重载这个方法,来让UIView使用不同的CALayer来显示

+[UIView animateWithDuration:animations:completion:] 内部大概是如何实现的?

  • animateWithDuration:这就等于创建一个定时器
  • animations:这是创建定时器需要实现的SEL
  • completion:是定时器结束以后的一个回调block

以上只是自己的理解,不一定正确,有对这个有研究的朋友请告知下

什么时候会发生「隐式动画」?

当改变CALayer的一个可做动画的属性,它并不能立刻在屏幕上体现出来.相反,它是从先前的值平滑过渡到新的值。这一切都是默认的行为,你不需要做额外的操作,这就是隐式动画

如何处理异步的网络请求?

异步请求:会单独开一个线程去处理网络请求,主线程依然处于可交互状态,程序运行流畅

    // POST请求
    NSString *urlString = @"www.baidu.com";
    // 创建url对象
    NSURL *url = [NSURL URLWithString:urlString];
    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
    // 创建参数字符串对象
    NSString *parmStr = [NSString stringWithFormat:@"参数"];
    // 将字符串转换为NSData对象
    NSData *data = [parmStr dataUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:data];
    [request setHTTPMethod:@"POST"];
    // 创建异步连接
    [NSURLConnection connectionWithRequest:request delegate:self];

然后实现代理方法

// 服务器接收到请求时
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
}
// 当收到服务器返回的数据时触发, 返回的可能是资源片段
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
}
// 当服务器返回所有数据时触发, 数据返回完毕
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
}
// 请求数据失败时触发
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    NSLog(@"%s", __FUNCTION__);
}

frame 和 bounds 的区别是什么?

  • frame相对于父视图,是父视图坐标系下的位置和大小。bounds相对于自身,是自身坐标系下的位置和大小。
  • frame以父控件的左上角为坐标原点,bounds以自身的左上角为坐标原点

如何把一张大图缩小为1/4大小的缩略图?

let data = UIImageJPEGRepresentation(image, 0.25)

还有一些题将写在第二篇文章里面,以上答案若有错误,请各位指出

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

推荐阅读更多精彩内容

  • 1. 父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。 1.1 深拷贝同浅拷贝...
    iYeso阅读 1,840评论 0 13
  • 父类实现深拷贝时,子类如何实现深度拷贝。父类没有实现深拷贝时,子类如何实现深度拷贝。• 深拷贝同浅拷贝的区别:浅拷...
    JonesCxy阅读 948评论 1 7
  • • 深拷贝同浅拷贝的区别:浅拷贝是指针拷贝,对一个对象进行浅拷贝,相当于对指向对象的指针进行复制,产生一个新的指向...
    WSGNSLog阅读 1,168评论 0 1
  • 一弦叹,恐无缘,愁思难断,心尖绪如帆,穿时光坠流年,已是双鬓青丝换。 二弦叹,千古情,独守梦影,相思孤月映,酌芳尊...
    迪迪大魔王kd阅读 893评论 5 8
  • 今天忘了忽悠爸爸拖地,但是回家发现已经干完了。在这里表扬一下。 晰晰今天去医院针灸,特别乖,不哭不闹的,让不动就不...
    晰晰麻麻阅读 220评论 0 0