c语言 面试题 多选题,iOS面试题-选择题

1.定义协议时,在协议名称后面加上的作用是:A、B、C

A.新定义的协议遵守 协议

B.新定义的协议是 协议的子协议

C.遵守新定义的协议的对象,也必须遵守 协议

D.遵守新定义的协议的对象,必须是 NBObject 的子类

解析:如果一个协议继承于另外一个协议,声明方法为尖括号里面填入父协议名称。

@protocol SonProtocol @end

既然代表是继承关系,那么A、B、C都符合

2.以下代码存在的问题是:C

dispatch_queue_t queue = dispatch_queue_create("com.apple.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(actionTime:) userInfo:nil repeats:YES];

});

- (void)actionTime:(NSTimer *)time {

NSLog(@"------ %@",[NSDate date]);

}

A.运行时崩溃

B.死锁

C.定时器不执行

D.定时器只执行一次

解析:首先看 DISPATCH_QUEUE_CONCURRENT 并发队列 和 dispatch_async 异步执行,应该不会产生死锁问题

所以此处考察的是 NSTimer 的用法,确切说是 NSTimer 在子线程中的应用

主线程的 RunLoop 是默认开启的,但是在子线程中需要手动启动 RunLoop 对象才能进入运行循环,从而发挥定时器的作用

代码修改如下可以正常运行:

dispatch_queue_t queue = dispatch_queue_create("com.apple.www", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(actionTime:) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

// 这里需要注意不要使用[[NSRunLoop currentRunLoop] run],因为会无法终止这个 RunLoop

// 而且这里必须是 NSDefaultRunLoopMode,使用 NSRunLoopCommonModes 的话定时器不执行

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

});

- (void)actionTime:(NSTimer *)time {

NSLog(@"------ %@",[NSDate date]);

}

// 必要的时候使用 CFRunLoopStop(CFRunLoopGetCurrent()); 停止RunLoop

或者是改成这样:在主线程中设置定时器

dispatch_async(dispatch_get_main_queue(), ^{

[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(actionTime:) userInfo:nil repeats:YES];

});

- (void)actionTime:(NSTimer *)time {

NSLog(@"------ %@",[NSDate date]);

}

3.以下哪些情况容易造成循环引用:A、B、C、D

A. dispatch_async 的 block 中使用 self

B. 使用 strong 修饰的 delegate 属性

C. self 作为 NSNotificationCenter 的 observer

D. self 作为所持有的 NSTimer 的 target

延伸小测试:以下情景中有哪些会造成循环引用?

4.以下哪些类跟 UIView 有继承关系(直接、间接的父类或子类):A、D

A. UIControl

B. UIGestureRecognizer

C. CALayer

D. UIResponder

解析:

UIControl : UIView

UIGestureRecognizer : NSObject

CALayer : NSObject

UIResponder : NSObject

UIView : UIResponder

所以 UIControl : UIView : UIResponder 答案:A、D

UIGestureRecognizer、CALayer 是 UIView 的属性类,但不存在继承关系

5.以下关于 OC 消息机制说法不正确的是:B、F

A. OC 的实例对象的 isa 指针指向它的类对象,类对象的 isa 指针指向它的元类对象

B. OC 调用一个未实现的实例方法,我们可以在 NSObject 的 resolveClassMethod 中进行添加方法进行补救

C. OC 可以运用运行时特性向 Class 的对象中动态添加方法

D. OC 的实例方法是存放在相应实例对象的 methodList 中,静态方法存在相应类对象的 methodList 中

E. OC 可以运用运行时特性向对象的 Category 中实现动态绑定属性,达到 Category 添加成员变量的效果

F. OC 可以运用运行时特性通过 class_addIvar() 向编译好的 Class 添加成员变量

解析:A 正确,可以参考下方大图

26ec0262f081

类、元类 isa 指向

解析:B 错误, resolveClassMethod 方法是针对类方法的决议,如果是实例方法,需要通过 resolveInstanceMethod,示例代码如下

+ (BOOL)resolveInstanceMethod:(SEL)sel{

if (sel == @selector(test)) {

IMP imp = [self instanceMethodForSelector:@selector(myClassMethod)];

class_addMethod(self, sel, imp, "v@:");

return YES;

}

return YES;

}

- (void)myClassMethod {

NSLog(@"resolveInstanceMethod");

}

解析 E 正确,实现代码如下:

@interface UIImageView (test)

@property(nonatomic, strong) NSObject *style;

@end

@implementation UIImageView (test)

static char styleKey;

- (void) setStyle:(NSObject *) style

{

objc_setAssociatedObject(self, &styleKey, style, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

}

- (NSObject *) style

{

return objc_getAssociatedObject(self, &styleKey);

}

@end

解析 F 错误

不能向编译后得到的类中增加实例变量,只能向运行时创建的类中添加实例变量。

因为编译后的类已经注册在 runtime 中,类结构体中的 objc_ivar_list 实例变量的链表和instance_size 实例变量的内存大小已经确定,同时 runtime 会调用 class_setIvarLayout 或 class_setWeakIvarLayout 来处理 strong weak 引用。所以不能向存在的类中添加实例变量。

运行时创建的类是可以添加实例变量,调用 class_addIvar 函数。但是得在调用 objc_allocateClassPair 之后,objc_registerClassPair 之前,原因同上。

6.在HTTP请求中,返回代码401和500代表下列哪两种状态:B、C

A:请求网页不存在

B:未授权

C:服务器内部错误

D禁止访问

参考:http协议的状态码

7.以下代码输出的日志是:E

dispatch_sync(dispatch_get_main_queue(), ^{

printf("1");

});

printf("2");

A. 12

B. 21

C.1

D.2

E. 无输出

解析:dispatch_sync在等待block语句执行完成,而block语句需要在主线程里执行,所以dispatch_sync如果在主线程调用就会造成死锁;dispatch_sync是同步的,本身就会阻塞当前线程,也即主线程。而又往主线程里塞进去一个block,所以就会发生死锁。

8.在开发过程中,block的使用很容易造成内存泄漏,对于下面代码会不会造成内存问题? 需要如何处理?:B

[UIView animateWithDuration:0.25 animations:^{

self.alpha = 0;

}];

A.会造成内存问题

B. 不会造成内存问题

会的话, 要如何处理_______

解析:此处block的使用不会造成循环引用,也不存在内存泄漏

9.以下代码第二行编译不通过,修改不正确的是:D

NSError * error = nil;

NSError ** plError = &error;

A. __strong NSError ** pError = &error;

B. NSError __strong ** pError = &error ;

C. NSError * __strong * pError = &error;

D. NSError ** __strong pError = &error;

解析:pError实例对象跟前一定有*修饰

10.runloop Observer 可以监听的事件为:A、D

A、进入runloop和退出runloop

B、执行完timer 事件

C、执行source事件之前和执行完source事件

D、等待前和唤醒后

解析:

kCFRunLoopEntry = (1UL << 0), 进入工作

kCFRunLoopBeforeTimers = (1UL << 1), 即将处理Timers事件

kCFRunLoopBeforeSources = (1UL << 2), 即将处理Source事件

kCFRunLoopBeforeWaiting = (1UL << 5), 即将休眠

kCFRunLoopAfterWaiting = (1UL << 6), 被唤醒

kCFRunLoopExit = (1UL << 7), 退出RunLoop

kCFRunLoopAllActivities = 0x0FFFFFFFU 监听所有事件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值