1.以下变量名合法的是(A) A. it_is_OK B. a4 C. flag-type D. a/b/c
注释: 数字、字母、下划线,都可以为变量命名。做为变量名的开头不能为数字。
2.一下选项中,合法的赋值语句是 (C)
A. a == 1; B. int a = b = c = 5; C. int a = 3; D. a++;-
A == 为判断语句,值返回为0或1
B 在变量说明中,不允许连续给多个变量赋初值。必须写为: int a = 5; b = 5; c = 5;
D 自加加和自减减只能是常量
3. int a = 27,b = 5,c = 10, d = 4;则 a/d*d+a%d+a/d 的值为(C)
A. 38 B. 36.75 C. 33 D. 37
4. #define SQUAKE(a) ((a++)*(++a))
int a= 5; int b = SQUAKE(a); 则b的值为 (C)
A. 25 B. 30 C.35 D.42
注释:程序是按照步骤来的,如果是a++的话,在那一行代码中,a的值是不变的,下一行才发生变化,++a则是在那一行已经发生了变化。
5. 若进栈序列为1,2,3,4,进栈过程中可以出栈,则下列不可能的一个出栈序列是(C)。
A 1.2.3.4 //长度为1,进一个,出一个
B 4.3.2.1 //长度为4,4个全部进,再一个个出
C 3.4.1.2 //长度为2,则为2,3,4,1
D 2.4.3.1 //长度为3,先进1,2出2,再进3,4之后出4,3最后出1
注释:栈是先进后出。
6. 关于Object-C内存管理机制错误的是 (C)
A. 当使用alloc方法创建对象,其计数器的值为1;
B. 调用retain方法时,其计数器的值增加1;
C. 使用copy方法创建对象时,其计数器的值减少1;
D. 当计数器为0时,系统自动调用dealloc方法来释放内存中的对象
7. Object-C声明一个类所用到的编译指令是(A)
A. @interface SomeClass B @protocol SomeClass C @implementation SomeClass D. @autorelease SomeClass
8. 使用protocol,声明一组可选择实现与否的函数时,需要在声明的前一行加上(B)
A. @required B. @optional C. @interface D. @protocol
9. 在UIKit中,frame与bounds的区别是(C)
A. frame 是 bounds 的别名 B. frame是bounds的继承类
C. frame的参考系是父视图坐标,bounds的参考系是自身的坐标
D. frame的参考系是自身的坐标,bounds的参考系是父视图的坐标
注释:bounds的原点是(0,0)点(就是view本身的坐标系统,默认永远都是0,0点,除非认为setbounds),而frame的原点却是任意的(相对于父视图中的坐标位置)。
10. 在一个UIViewController中,函数(A)
-(instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil; //----(1)
-(void)viewDidLoad; //----(2)
-(void)viewWillAppear:(BOOL)animated; //----(3)
-(void)viewDidAppear:(BOOL)animated; //----(4)
A. (1) (2) (3) (4) B. (3) (1) (2) (4) C. (3) (4) (1) (2) D. (1) (3) (4) (2)
-[ViewController initWithCoder:]
-[ViewController loadView]
-[ViewController viewDidLoad]
-[ViewController viewWillAppear:]
-[ViewController viewDidAppear:]
<div class="crayon-line crayon-striped-line" id="crayon-578db04378d4e988019045-2"><span class="crayon-o">*</span><span class="crayon-h"> </span><span class="crayon-v">xib</span><span class="crayon-o">/</span><span class="crayon-v">storyboard</span>:<span class="crayon-o">-</span><span class="crayon-v">initWithCoder</span><span class="crayon-o">:</span>,而非<span class="crayon-v">xib</span><span class="crayon-o">/</span><span class="crayon-v">storyboard</span>的是<span class="crayon-o">-</span><span class="crayon-v">initWithNibName</span><span class="crayon-v">:bundle</span><span class="crayon-o">:</span>然后<span class="crayon-o">-</span><span class="crayon-t ">init</span></div><div class="crayon-line" id="crayon-578db04378d4e988019045-3"><span class="crayon-o">*</span><span class="crayon-h"> </span><span class="crayon-o">-</span><span class="crayon-t ">loadView</span></div><div class="crayon-line crayon-striped-line" id="crayon-578db04378d4e988019045-4"><span class="crayon-o">*</span><span class="crayon-h"> </span><span class="crayon-o">-</span><span class="crayon-t ">viewDidLoad</span></div><div class="crayon-line" id="crayon-578db04378d4e988019045-5"><span class="crayon-o">*</span><span class="crayon-h"> </span><span class="crayon-o">-</span><span class="crayon-v">viewWillAppear</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-578db04378d4e988019045-6"><span class="crayon-o">*</span><span class="crayon-h"> </span><span class="crayon-o">-</span><span class="crayon-v">viewDidAppear</span><span class="crayon-o">:</span></div><div class="crayon-line" id="crayon-578db04378d4e988019045-7"><span class="crayon-o">*</span><span class="crayon-h"> </span><span class="crayon-o">-</span><span class="crayon-v">viewWillDisappear</span><span class="crayon-o">:</span></div><div class="crayon-line crayon-striped-line" id="crayon-578db04378d4e988019045-8"><span class="crayon-o">*</span><span class="crayon-h"> </span><span class="crayon-o">-</span><span class="crayon-v">viewDidDisappear</span><span class="crayon-o">:</span></div>
11. 代码段:
NSMutableString * str1 = [[NSMutableString alloc] initWithString:@"aabbcc"];
NSString * str2 = [str1 copy];
NSString * str3 = [str2 copy];
NSLog(@"%p",str1); //......1
NSLog(@"%p",str2); //......2
NSLog(@"%p",str3); //......3
对注释标记中的1、2、3三行,()
A. 1、2、3输出结果相同 B. 1、2输出结果相同,并与3不同 C.2、3输出结果相同,并与1不同 D.1、2、3输出结果各不相同
注释:
打印输出结果为:
2016-07-18 21:32:09.833 笔试检测[5012:664031] 0x7fccaaf2a1b0
2016-07-18 21:32:09.834 笔试检测[5012:664031] 0xa006363626261616
2016-07-18 21:32:09.834 笔试检测[5012:664031] 0xa006363626261616
12. 需要在ARC风格编写和编译的Xcode项目中引入手动内存分配和释放的文件,需要在文件的Compier Flage 上添加参数 (C)
A. - shared B. - fno - objc - arc C. - fobjc - arc D. 无法直接加入,只能将其中的内存管理代码删除再加入
13. 在没有navigationController的情况下,要从一个ViewController切换带另一个ViewController,应该使用 (C)
A. [self.navigationController pushViewController:nextViewController animated:YES];
B. [self.view addSubview:nextViewController.view];
C. [self pushViewController:nextViewController animated:YES];
D. [self presentModalViewController:nextViewController animated:YES];
注释:
14. 对于下面的代码(B)
@implementation TestViewController
-(void) setVar :(int)var{
self.var = var;
}
A. 应该将var synthesize B. 调用会出现死循环 C. 正常 D. 返回值错误
注释:应改为 _var = var;
1. 面向对象的特征有 继承、封装、多态。
2. 实例化一个UITableView对象时必须要实现的代理有
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
3. 写一个“标准”宏MIN,这个宏输入两个参数返回较小的一个
#define MIN(A,B) ((A)<(B)?(A):(B))
4. 在使用Pods管理第三方软件是,需要更新某个第三方库时,一把会在终端进行操作的指令是 pod install 、 pod update 。
1. 谈谈iOS中assign,copy,retain之间的区别;以及weak和strong的区别;并说出这行代码写法有什么问题:
@property (copy) NSMutableArray * array;(9 分)
assign:这个是简单赋值,不更改引用引用计数;
copy:建立引用计数为一的对象,然后释放旧对象;
retain:释放旧对象,将旧对象的值赋予输入对象,再提高输入对象的引用索引计数;
<pre name="code" class="objc">当把属性声明为retain时,setter和getter方法内部实现
- (void)setName:(NSString *)name{
if (_name != name) {
[ _name release];
_name = [name retain];
}
}
- (NSString *)name{
return [[ _name retain] autorelease];
}
当把属性声明为copy时,setter和getter方法内部实现<p>- (void)setName:(NSString *)name{</p><p> if (_name != name) {</p><p> [ _name release];</p><p> _name = [name copy];</p><p> }</p><p>}</p><p>- (NSString *)name{</p><p> return [[ _name retain] autorelease];</p><p>}</p>
当把语义特性声明为assign时,setter和getter时方法内部实现
- (void)setName:(NSString *)name{
_name = name;
}
- (NSString *)name{
return _name;
}
assign :是对oc基础数据类型(CGRect,CGPoint)和C数据类型(float int);
copy:是对字符串NSString;
retain:是对其他NSObject 和其子类;
参考李明杰老师的内存管理指南之strong和weak指针:ARC指南1 - strong和weak指针
这行代码有两个问题:
1、添加,删除,修改数组内的元素的时候,程序会因为找不到对应的方法而崩溃.因为copy就是复制一个不可变NSArray的对象;
2、使用了atomic属性会严重影响性能。
atomic是oc使用的一种线程保护技术,是为了防止在写未完成的时候被其他线程读取,造成数据错误,而这种机制是很耗资源的,在iphone这小型设备上如果没有使用多线程之 间的通讯,那么使用nonatomic是一个非常好的选择
注:
oc的内存管理,第一:retain copy都是在手动内存管理中,赋值oc对象常用的防止内存泄露的方法,当A 要赋值给B时,A完成赋值操作后,将自己release,而B则将自己原持有的对象地址release,并持有A的对象及引用计数,这样就保证两个数据块的引用计数始终为1或0,程序中最后一位引用者release时,才能保证这块内存被很好的释放;
2. 写一个方法,要求把一个二维数组转换为字典类型,要求数组中每个元素中的第一个元素(NSString * 类型)作key, 第二个元素作为Value。根据你写的代码,下面的测试用例会输出什么?(9 分)
NSArray * changeArray = @[@[@"key1",@"value1"],@"NSString",@[@"key3"],@[],@[@'A',@123.4]];
NSLog(@"GetDict = %@",[self changeArrayFromDictionary:changeArray]);
//方法代码:
- (NSDictionary *)changeArrayFromDictionary:(NSArray *)array{
NSMutableDictionary * mDic = [NSMutableDictionary dictionary];
for (NSArray * subArray in array) {
if (subArray.count >= 2) {
NSString * key = [NSString stringWithFormat:@"%@",subArray[0]];
NSString * value = [NSString stringWithFormat:@"%@",subArray[1]];
[mDic setValue:value forKey:key];
}else if (subArray.count == 1){
NSString * key = [NSString stringWithFormat:@"%@",subArray[0]];
[mDic setValue:nil forKey:key];
}
}
return mDic;
}
GetDict = {
65 = "123.4";
key1 = value1;
}
3. 怎样实现一个单例模式的类,需要注意什么,可以给出思路。(9 分)
在objective-c中要实现一个单例类,至少需要做以下四个步骤:4、适当实现allocWitheZone,copyWithZone,release和autorelease。
下面以SurveyRunTimeData为例子:
static SurveyRunTimeData *sharedObj = nil; //第一步:静态实例,并初始化。
@implementation SurveyRunTimeData
+ (SurveyRunTimeData*) sharedInstance //第二步:实例构造检查静态实例是否为nil
{
@synchronized (self)
{
if (sharedObj == nil)
{
[[self alloc] init];
}
}
return sharedObj;
}
+ (id) allocWithZone:(NSZone *)zone //第三步:重写allocWithZone方法
{
@synchronized (self) {
if (sharedObj == nil) {
sharedObj = [super allocWithZone:zone];
return sharedObj;
}
}
return nil;
}
- (id) copyWithZone:(NSZone *)zone //第四步
{
return self;
}
4. 现有AViewController和BviewController,AViewController中有textField和button两个控件,BviewController中有tableBiew,数据源为array,
元素为dictionary(key = name)。假如在AViewController中点击button(事件为touchAction)后,push到BviewController,要求在
BviewController中点击cell后,pop到AviewController,并在textField中展示所选cell的name,要求分别用delegate和block实现。
(请在下方代码中插入你的代码,button,textField,tableView可直接使用,无需再实例化)。(9分)
AViewController.h
#import <UIKit/UIKit.h>
@interface AViewController : UIViewController
@end
#import "AViewController.h"
#import "BViewController.h"
@interface AViewController () <BViewControllerDelegate>
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *button;
-(IBAction)touchAction:(id)sender;
@end
@implementation AViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
-(IBAction)touchAction:(id)sender{
BViewController * BVc = [[BViewController alloc] init];
BVc.delegate = self;
[self.navigationController pushViewController:BVc animated:YES];
}
#pragma mark - BViewControllerDelegate
-(void)changeTextFieldText:(NSString *)text{
_textField.text = text;
}
BViewController.h
#import <UIKit/UIKit.h>
@protocol BViewControllerDelegate <NSObject>
-(void)changeTextFieldText:(NSString *)text;
@end
@interface BViewController : UIViewController
@property (nonatomic, strong) NSArray * dataArray;
@property (nonatomic, strong) id<BViewControllerDelegate> delegate;
@end
BViewController.m
#import "BViewController.h"
@interface BViewController ()<UITableViewDelegate,UITableViewDataSource>
@end
@implementation BViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArray = @[@{@"key":@"name1"},@{@"key":@"name2"},@{@"key":@"name3"},@{@"key":@"name4"},@{@"key":@"name5"}];
UITableView * table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
table.delegate = self;
table.dataSource = self;
[self.view addSubview:table];
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * cellIdentifier = @"cellIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.dataArray[indexPath.row] objectForKey:@"key"];
return cell;
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[self.delegate changeTextFieldText:[self.dataArray[indexPath.row] objectForKey:@"key"]];
[self.navigationController popViewControllerAnimated:YES];
}
AViewController.h
#import <UIKit/UIKit.h>
@interface AViewController : UIViewController
@end
AViewController.m
#import "AViewController.h"
#import "BViewController.h"
@interface AViewController ()
@property (weak, nonatomic) IBOutlet UITextField *textField;
@property (weak, nonatomic) IBOutlet UIButton *button;
-(IBAction)touchAction:(id)sender;
@end
@implementation AViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
-(IBAction)touchAction:(id)sender{
BViewController * BVc = [[BViewController alloc] init];
[BVc changeTextFieldText:^(NSString *text) {
_textField.text = text;
}];
[self.navigationController pushViewController:BVc animated:YES];
}
#import <UIKit/UIKit.h>
typedef void(^ChangeTextBlock)(NSString * text);
@interface BViewController : UIViewController
@property (nonatomic, strong) NSArray * dataArray;
@property (nonatomic, copy) ChangeTextBlock changeTextBlock;
-(void)changeTextFieldText:(ChangeTextBlock)block;
@end
BViewController.m
#import "BViewController.h"
@interface BViewController ()<UITableViewDelegate,UITableViewDataSource>
@end
@implementation BViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.dataArray = @[@{@"key":@"name1"},@{@"key":@"name2"},@{@"key":@"name3"},@{@"key":@"name4"},@{@"key":@"name5"}];
UITableView * table = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
table.delegate = self;
table.dataSource = self;
[self.view addSubview:table];
}
-(void)changeTextFieldText:(ChangeTextBlock)block{
self.changeTextBlock = block;
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString * cellIdentifier = @"cellIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.textLabel.text = [self.dataArray[indexPath.row] objectForKey:@"key"];
return cell;
}
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if (self.changeTextBlock != nil) {
self.changeTextBlock([self.dataArray[indexPath.row] objectForKey:@"key"]);
}
[self.navigationController popViewControllerAnimated:YES];
}
请使用你认为比较规范的风格(书写规范、命名规范等)重写以下代码。(10)
#import "UserModel.h"
typedef enum{
UserSex_Man,
UserSex_Woman
}UserSex;
@interface UserModel : NSObject
@property(nonatomic,strong)NSString *name;
@property(assign,nonatomic)int age;
@property(nonatomic,assign)UserSex sex;
-(id)initUserModelWithUserName:(NSString*)name withAge:(int)age;
-(id)doLogin;
优化部分
1)enum建议使用 NS_ENUM 和 NS_OPTIONS 宏来定义枚举类型,参见官方的 Adopting Modern Objective-C 一文:
//定义一个枚举
typedef NS_ENUM(NSInteger, CYLSex) {
CYLSexMan,
CYLSexWoman
};
int -> NSInteger
unsigned -> NSUInteger
float -> CGFloat
动画时间 -> NSTimeInterval
同时考虑到age的特点,应使用NSUInteger,而非int。 这样做的是基于64-bit 适配考虑,详情可参考博文
《64-bit Tips》。
4)doLogIn方法不应写在该类中:虽然LogIn的命名不太清晰,但笔者猜测是login的意思,而登录操作属于业务逻辑,观察类名UserModel,以及属性的命名方式,应该使用的是MVC模式,并非MVVM,在MVC中业务逻辑不应当写在Model中。(如果是MVVM,抛开命名规范,UserModel这个类可能对应的是用户注册页面,如果有特殊的业务需求,比如:login对应的应当是注册并登录的一个Button,出现login方法也可能是合理的。)
5)doLogIn方法命名不规范:添加了多余的动词前缀。 请牢记:
如果方法表示让对象执行一个动作,使用动词打头来命名,注意不要使用do,does这种多余的关键字,动词本身的暗示就足够了。
6)-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;方法中不要用with来连接两个参数:withAge:应当换为age:,age:已经足以清晰说明参数的作用,也不建议用andAge::通常情况下,即使有类似withA:withB:的命名需求,也通常是使用withA:andB:这种命名,用来表示方法执行了两个相对独立的操作(从设计上来说,这时候也可以拆分成两个独立的方法),它不应该用作阐明有多个参数,比如下面的://错误,不要使用"and"来连接参数
- (int)runModalForDirectory:(NSString *)path andFile:(NSString *)name andTypes:(NSArray *)fileTypes;
//错误,不要使用"and"来阐明有多个参数
- (instancetype)initWithName:(CGFloat)width andAge:(CGFloat)height;
//正确,使用"and"来表示两个相对独立的操作
- (BOOL)openFile:(NSString *)fullPath withApplication:(NSString *)appName andDeactivate:(BOOL)flag;
硬伤部分
1)在-和(void)之间应该有一个空格
2)enum中驼峰命名法和下划线命名法混用错误:枚举类型的命名规则和函数的命名规则相同:命名时使用驼峰命名法,勿使用下划线命名法。
3)enum左括号前加一个空格,或者将左括号换到下一行
4)enum右括号后加一个空格
5)UserModel :NSObject 应为UserModel : NSObject,也就是:右侧少了一个空格。
6)@interface与@property属性声明中间应当间隔一行。
7)两个方法定义之间不需要换行,有时为了区分方法的功能也可间隔一行,但示例代码中间隔了两行。
8)-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;方法中方法名与参数之间多了空格。而且- 与(id)之间少了空格。
9)-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;方法中方法名与参数之间多了空格:(NSString*)name前多了空格。
10)-(id)initUserModelWithUserName: (NSString*)name withAge:(int)age;方法中(NSString*)name,应为(NSString *)name,少了空格。
11)doLogIn方法命名不清晰:笔者猜测是login的意思,应该是粗心手误造成的。
12)第二个@property中assign和nonatomic调换位置。
修改后:
typedef NS_ENUM(NSInteger,WLUserSex) {
WLUserSexMan,
WLUserSexWoman
};
@interface UserModel : NSObject<NSCopying>
@property(nonatomic, copy, readonly) NSString *name;
@property(nonatomic, assign, readonly) NSUInteger age;
@property(nonatomic, assign, readonly) WLUserSex sex;
- (instancetype)initWithName:(NSString *)name age:(int)age sex:(WLUserSex)sex;
+ (instancetype)userWithName:(NSString *)name age:(int)age sex:(WLUserSex)sex;
-(id)login;