### 牛客网 iOS 题 107-126
107.NSRunLoop 以下描述错误的是( )
- RunLoop 并不是由系统自动控制的
- 有三类对象可以被 RunLoop 监控:sources,timers,observers
- 线程是默认启动 RunLoop 的
- NSTimer 可手动添加到新建的 NSRunLoop 中
答案:3
- RunLoop 的作用在于当有事情要做的时候它使当前的 thread 工作,没有事情做时又使 thread 休眠 sleep。RunLoop 并不是由系统自动控制的,尤其是对那些新建的次线程需要对其进行显示的控制。
- 每一个线程都有自己的 RunLoop,主线程是默认开启的,创建的子线程需要手动开启,因为 NSApplication 只启动 main application thread。
- NSTimer 默认添加到当前的 NSRunLoop 中,也可以手动制定添加到自己新建的 NSRunLoop 中
108.参考90题
109.参考22题
110.参考20题
111.下面关于线程管理错误的是( )
- GCD 在后端管理着一个线程池
- NSOperationQueue 是对 NSThread 的更高层封装
- NSThread 需要自己管理线程的生命周期
- GCD 可以根据不同优先级分配线程
答案:2
NSOperationQueue 是对 GCD 的更高层封装
112.关于 Objective-C 中属性的说明,以下错误的是( )
- readwrite 是可读可写特性,需要生成 getter方法和 setter 方法
- readonly 是只读特性,只有 getter 方法,没有 setter 方法
- assign 是赋值属性,setter 方法将传入参数赋值给实例变量
- retain 表示持有特性,copy 属性表示拷贝属性,都会建立一个相同的对象
答案:4
copy 是创建一个新对象,retain 是创建一个指针,引用对象计数加1
113.C 和 Objective-C 的混合使用,以下描述错误的是( )
- cpp 文件只能使用 C/C++ 代码
- cpp 文件 include 的头文件中,可以出现 Objective-C 代码
- mm 文件中混用 cpp 直接使用即可
- cpp 使用 Objective-C 的关键是使用接口,而不能直接使用代码
答案:2
cpp 文件以及头文件都只能用 c/c++代码
114.delegate 中的 property 使用以下哪个属性( )
- assign
- retain
- copy
- strong
答案:1
assign 防止循环引用
115.以下哪一段代码不会抛出异常( )
NSArray *array = @[1, 2, 3]; NSNumber *number = array[3];
NSDictionary *dict = @{@"key":nil};
NSString *str = nil; NSString *str2 = [str substringFromIndex:3];
NSString *str = @"hi"; NSString *str2 = [str substringFromIndex:3];
答案:3
- OC 数组中的元素不能使基本数据类型,必须是对象,而且 array[3]下标越界;
- 字典中键值对不能为 nil,运行时崩溃
- OC 中向空对象发送消息,不执行任何操作,不报错,不崩溃
- 数组下标越界,运行时崩溃
116.参考题1
117. float x 与“零值”比较的 if 语句是?
if(x == 0)
if(x < 0.00001f)
if(fabs(x) < 0.00001f) 或 if(Math.abs(x) < 0.00001f)
if(x > -0.00001f)
答案:3
float 和 double 都是有精度限制,应该用 |x-0| < err 来判断,这里 |x-0| 表示绝对值,err 表示限定误差。
118.一次鼠标单击会产生下列哪些事件( )
- onmousemove
- onmousedown
- onmouseup
- onclick
- onmouseover
答案:2,3,4
119.UIView 的以下哪些属性是 Animatable 的:( )
- backgroundColor
- opaque
- transform
- contentStretch
答案:1,3,4
opaque 是 BOOL 型变量。如果要调整透明度,应该是 alpha 属性。
120.[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopModebeforeDate:[NSDate distantFuture]];
这段代码的作用是
- 设置当前线程的运行模式
- 暂停当前线程一段时间
- 在当前线程中进行一次消息轮询
- 设置当前线程的最大运行时间
答案:3
进行一次消息轮询,监听线程是否有消息输入(default 模式),有就线程开始工作,没有就休眠。
121.下面的定义中,错误的个数为:( )
NSString a[] = {@"abc", @"def"};
NSArray *a = @[@"abc", @"def"];
NSArray *a = [NSArray arrayWithObjects:@"abc", @"def"];
NSArray *a = [NSMutableArray arrayWithArray:@[@"abc"]];
答案:2
NSString *a[] = {@"abc", @"def"};
NSArray *a = [NSArray arrayWithObjects:@"abc", @"def", nil];
122.应用申明一下哪些权限可以被系统授予后台运行的权限?
- 视频播放应用
- 音乐播放应用
- 地理位置应用
- VoIP 应用
- 杂志新闻类需要更新内容的应用
答案:2,3,4,5
123.以下代码欲在 NSOperation 子线程中异步请求网络数据,请在注释处写上一段代码以满足要求。finished_代表异步请求结束的标志变量。请选出有用的选项:
- (void) start {
if (![self isCancelled]) {
connection_ = [[NSURLConnection alloc]initWithRequest:[NSURLRequest requestWithURL:download_url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15] delegate:self];
if (connection_ != nil) {
executing_ = YES;
} else {
finished_ = YES;
}
while (!finished_) {
// 代码放入此处
}
}
else {
finished_ = YES;
}
}
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithinterval:0.1]];
[[NSThread currentThread]waitForTimeinterval:0.1];
[NSThread sleepForTimeinterval:0.1];
答案:1
只有主线程的NSRunLoop会默认启动,自己新起的线程,要自己手动调用RunLoop。
这里新起了一个线程,调用NSURLConnection的异步方法,如果不设置RunLoop,则NSURLConnection的delegate函数不会被运行,因为线程已经结束。在NSURLConnection的delegate方法中去设置finished_变量为YES,线程才会退出while循环而结束。
124.在定义属性时,下面哪些数据类型可以使用 retain 和 copy:
- NSArray
- float
- int
- NSString
- NSNumber
- NSInteger
答案:1,4,5
copy 是在数据类型声明时,选择遵守 NSCopying 协议的才可以使用
9大基本类型不能使用 retain
NSInteger = long
125.C++/Java/Objective-C/C# 是如何体现面对对象思想的?
继承、封装、多态 ?
126.iOS 系统提供了哪些手势?选择一个自己写代码实现
- UITapGestureRecognizer敲击手势(单击和双击)
- UIPanGestureRecognizer(拖动手势)
- UIPinchGestureRecognizer(缩放手势)
- UISwipeGestureRecognizer(擦碰手势)
- UIRotationGestureRecognizer(旋转手势)
- UILongPressGestureRecognizer(长按手势)
UIView *gestureView = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 300, 300)];
gestureView.backgroundColor = [UIColor blackColor];
[self.view addSubview:gestureView];
/*---------------点击手势-------------*/
UITapGestureRecognizer *tap1 = [[UITapGestureRecognizer alloc ] initWithTarget : self action : @selector (tap1Action:)];
//注意:一个点击手势,只能识别一种手势,单击和双击是不同的两个手势
//设置点击的数量
tap1.numberOfTapsRequired = 1 ;
//设置点击的个数
tap1.numberOfTouchesRequired = 1 ;
//往gestureView上添加一个手势
[gestureView addGestureRecognizer:tap1];
UITapGestureRecognizer *tap2 = [[UITapGestureRecognizer alloc ] initWithTarget : self action : @selector (tap2Action:)];
tap2.numberOfTapsRequired = 2 ;
[gestureView addGestureRecognizer:tap2];
//如果参数中的手势出发了,则自身失效
[tap1 requireGestureRecognizerToFail:tap2];
/*---------------轻扫手势-------------*/
UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc ] initWithTarget : self action : @selector (swipe:)];
// 设置方向---向上轻扫
swipeGesture. direction = UISwipeGestureRecognizerDirectionUp;
[gestureView addGestureRecognizer:swipeGesture];
/*---------------平移手势-------------*/
// 平移手势(滑动)
UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc ] initWithTarget : self action : @selector (panAction:)];
[gestureView addGestureRecognizer:panGesture];
/*---------------长按手势-------------*/
// 长按手势
UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc ] initWithTarget : self action : @selector (longPress:)];
//设置长安的最短时间
longPressGesture.minimumPressDuration = 3;
[gestureView addGestureRecognizer:longPressGesture];
/*---------------旋转手势-------------*/
// 旋转手势
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc ] initWithTarget : self action : @selector (rotation:)];
[gestureView addGestureRecognizer:rotationGesture];
/*----------捏合手势--------------*/
UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc ] initWithTarget : self action : @selector (pinchAction:)];
[gestureView addGestureRecognizer:pinch];
}
//单击
- (void)tap1Action:(UITapGestureRecognizer *)tap1
{
NSLog(@" 单击 ");
}
//双击
- (void)tap2Action:(UITapGestureRecognizer *)tap2
{
NSLog(@" 双击 ");
}
//轻扫
- ( void )swipe:(UISwipeGestureRecognizer *)swipe
{
if (swipe. direction == UISwipeGestureRecognizerDirectionUp) {
NSLog(@" 向上清扫 ");
}
}
//平移
- ( void )panAction:(UIPanGestureRecognizer *)pan
{
CGPoint p = [pan locationInView:pan.view];
NSLog( @"%@" , NSStringFromCGPoint(p));
}
//长按
- ( void )longPress:(UILongPressGestureRecognizer *)longPress
{
if (longPress. state == UIGestureRecognizerStateBegan) {
NSLog(@" 开始长按 ");
} else if (longPress. state == UIGestureRecognizerStateEnded) {
NSLog(@" 结束长按 ");
}
}
//旋转
- ( void )rotation:(UIRotationGestureRecognizer *)rotation
{
//获取旋转角度---弧度
CGFloat r = rotation.rotation;
//弧度转角度
//180/Pi = x/r
NSLog(@"r is %.2f", 180 / M_PI * r);
}
//捏合
- (void)pinchAction:(UIPinchGestureRecognizer *)pinch
{
//获得捏合的比例
CGFloat scale = pinch.scale;
// pinch.view.transform = CGAffineTransformScale(pinch.view.transform, scale, scale);
pinch.view.transform = CGAffineTransformMakeScale(scale, scale);
}