iOS程序员面试分类模拟7_第1页
iOS程序员面试分类模拟7_第2页
iOS程序员面试分类模拟7_第3页
iOS程序员面试分类模拟7_第4页
iOS程序员面试分类模拟7_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

iOS程序员面试分类模拟7简答题1.

在UITableViewController中创建UITableViewCell时,initWithSytle:resuseIdentifier中的reuseIden(江南博哥)tifier有什么用?UITableViewCell的复用原理是怎么样的?正确答案:reuseIdentifier顺名思义是一个复用标识符,是一个自定义的独一无二的字符串,用来唯一地标记某种重复样式的UITableViewCell。系统是通过reuseIdentifier来复用已经创建了的指定样式的cell,iOS中表格的cell通过复用机制来提高加载效率,因为多数情况下表格中的cell样式都是重复的,只是数据模型不同而已。因此,系统可以在保证创建一定数量的cell的前提下(覆盖整个tableView),通过保存并重复使用已经创建的cell来提高加载效率和优化内存,避免不停地创建和销毁cell元素。

UITableViewCell的复用原理其实很简单,可以通过下丽一个简单的例子来理解。

开发时在UITableViewController类中写cell复用代码的基小模板如下:

/*可复用cell制作*/

-(UITableViewCell*)tableView:(UITableView*)tableView

cellForRowAtIndexPath:(NSIndexPath*)indexPath{

/*定义cell重用的静态标志符*/

staticNSString*cell_id=@"cell_id_demo";

/*优先使用可复用的cell*/

UITableViewCell*cell=[tableViewdequeueReusableCellWithIdentifier:cell_id];

/*如果要复用的cell还没有创建,那么创建一个供之后复用*/

if(cell=nil){

/*新创建cell并使用cell_id复用符标记*/

cell=[[UITableViewCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:cell_id];

}

/*配置cell数据*/

cell.textLabe1.text=[NSStringstringWithFormat:@"Cell%i",countNumber];

/*其他cell设置...*/

returncell;

}

代码这样写的原因是通过调用当前tableView的dequeueReusableCellWithIdentifier方法判断指定的reuseIdentifier是否有可以重复使用的cell。如果有,那么会返回可复用的cell,cell就绪之后便可以开始更新cell的数据;如果没有可以复用的cell,那么返回nil,然后会进入后面的if语句,此时创建新的cell并给它标记一个标识符reuseIdentifier。注意上面的if语句并不是每次都创建一次新的cell,然后全部重复利用新创建的那一个cell,这是对cell复用机制的误解。事实是要创建足够数量的可覆盖整个tableView的cell之后才会开始复用之前的cell(UITableView中有一个visiableCells数组保存当前屏幕可见的cell,还有一个reusableTableCells数组用来保存那些可复用的cell)。下面通过测试来验证。

如何简洁清楚地展示UITableViewCelI的复用机制呢?下面的例子是创建最基本的文本cell,并创建一个cell创建计数器,每次新创建cell计数器加1然后显示在cell上,如果是复用的cell,那么会显示是复用的哪一个cell,测试代码如下:

/*分区个数设置为1*/

-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{

return1;

}

/*创建20个cell,保证覆盖并超出整个tableView*/

-(NSInteger)tableView:(UITableView*)tableViewnumberOfRowsInSection:(NSInteger)section{

return20;

}

/*cell复用机制测试*/

-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath{

/*定义cell重用的静态标志符*/

staticNSString*cell_id=@"cell_id_demo";

/*计数用*/

staticintcountNumber=1;

/*优先使用可复用的cell*/

UITableviewCell*cell=[tableViewdequeueReusableCellWithIdentifier:cell_id];

/*如果要复用的cell还没有创建,那么创建一个供之后复用*/

if(cell=nil){

/*新创建cell并使用cell_id复用符标记*/

cell=[[UITableViewCellalloc]initWithStyle:UITableviewCellStyleDefaultreuseIdentifier:cell_id];

/*计数器标记新创建的cell*/

cell.textLabe1.text=[NSStringstringWithFormat:@"Cell%i"countNumber];

/*计数器递增*/

countNumber++;

}

returncell;

}

运行在iPhone5S设备上(UITableViewController作为跟控制器,tableView覆盖整个屏幕),20个cell显示结果依次为(见图1和图2):

图1

cell刚好填满屏幕

图2

滑动复用的cell

Cell1、Cell2、Cell3、Cell4、Cell5、Cell6、Cell7、Cell8、Cell9、Cell10、Cell11、Cell12、Cell13、Cell14、Cell1、Cell2、Cell3、Cell4、Cell5、Cell6。

可以看出一共创建了14个cell,其中整个屏幕可显示13个cell,系统多创建一个的原因是保证在表格滑动显示半个cell时仍然能覆盖整个tableView。之后的6个cell就是复用了开始创建的那6个cell了。这样UITableViewCell复用的基本机制就很清楚了,还会有reloadData或者reloadRowsAtIndex等刷新表格数据的情况,可能会伴随新的cell创建和可复用cell的更新,但也是建立在基本复用机制的基础之上的。

2.

能否在一个视图控制器中嵌入两个tableView控制器?正确答案:可以,相当于视图和视图控制器的嵌套,视图可以添加子视图,视图控制器也可以添加子控制器。这种情况有时会被用到而且很重要,但是有一点容易被忽视,就是将子视图添加到了父视图却忘记将对应的控制器作为子控制器添加到父控制器,导致子视图能显示但是不能响应(没有对接好控制器)。例如在当前视图上放一个小尺寸的表格组件,也就是在UIViewController上添加一个UITableViewController子控制器及其子view。

/*假设有3个视图控制器,一个作为父控制器,两个作为子控制器*/

UIViewController*superVC=[[UIViewControlleralloc]init];

UITableViewController*subVC1=[[UITableViewControlleralloc]init];

UITableViewController*subVC2=[[UITableViewControlleralloc]init];

/*将子视图控制器添加到父视图控制器(要注意调整子视图的尺寸和位置合理显示,这里忽略)*/

[superVC.viewaddSubview:subVC1.view];

[superVCaddChildViewController:subVC1];

[superVC.viewaddSubview:subVC2.view];

[superVCaddChildViewController:subVC2];

/*子视图控制器的移除有对应的方法,但只能是子视图控制器主动从父视图控制器中移除*/

[subVC1.viewremoveFromSuperview];

[SubVC1removeFromParentViewController];

[subVC2.viewremoveFromSuperview];

[subVC2removeFromParentViewController];

此外,要注意和presentViewController方法添加子视图控制器的区别,上面手动添加子视图控制器是可以自由调整子视图的frame的(包括子视图位置和尺寸),而presentViewController是用于页面切换,切换后的子页面会覆盖整个屏幕而不可以自由调整子页面位置和尺寸,对应的子视图控制器移除方法为dismissViewControllerAnimated。

/*显示子视图控制器,completion后的代码块如果不为空,那么添加结束后会触发*/

[[parentVCpresentViewController:childVCanimated:NOcompletion:nil];

/*移除子视图控制器,completion后的代码块如果不为空,那么添加结束后会触发*/

[childVCdismissViewControllerAnimated:NOcompletion:nil];

3.

一个tableView是否可以关联两个不同的datasource数据源?正确答案:多个数据源是完全可以的,问题的重点是如何关联,因为将数据源(Model)和tableView视图的对接工作是程序员完成的,所以数据源的多少没有根本影响。处理上可以分开依次对接,也可以通过数据的集合操作先将数据整理合并成一个数据源,然后对接。

例如,一个表格中的每个cell显示的是一个人的基本信息,为了简单这里假设只有一个头像和I一个姓名。假设有两个数据源,一个数据源是头像的url数组;另一个是姓名的字符串数组,对接时完全可以分开在cell数据回调中对接,也可以将两个数组合并然后对接。

合并数据用到的数据模型:

@interfaceModel:NSObject

@property(nonatomic,copy)NSString*name;

//姓名

@property(nonatomic,copy)NSString*url;

//图片

@end

数据源缓冲器:

/*数据源*/

@property(nonatomic,strong)NSArray*nmne_datasource;

@property(nonatomic,strong)NSArray*url_datasource;

@property(nonatomic,strong)NSMutableArray*datasource;

处理多数据源:

/*请求数据*/

-(void)request{

/*姓名数据源*/

_name_datasource=@[@"张三",@"李四",@"小明",@"小李"];

_url_datasource=@[@"male",@"male",@"male",@"male"];

/*合并数据源*/

for(inti;i<_name_datasource.count;i++){

Model*model=[[Modelalloc]init];

=_name_datasource[i];

model.url=_url_datasource[i];

[_datasourceaddObject:model];

}

}

数据对接:

/*cell数据回调*/

-(UITableViewCell*)tableView:(UITableView*)tableViewcellForRowAtIndexPath:(NSIndexPath*)indexPath{

staticNSString*identifier=@"identifier";

/*自制cell组件*/

AccountCell*cell=[[AccountCellalloc]initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:identifier];

/**多数据源分开对接:**/

/*头像*/

[cell.avatarsetImage:[UIImageimageNamed:_url_datasource[indexPath.row]];

/*姓名*/

.text=_name_datasource[indexPath.row];

/*或者:*/

/**数据源合并后对接**/

/*取出对应数据模型*/

Model*model=_datasource[indexPath.row];

/*头像*/

[cell.avatarsetImage:[UIImageimageNamed:model.url]];

/*姓名*/

.text=;

returncell;

}

4.

如何对UITableView的滚动加载进行优化,防止卡顿?正确答案:表格视图(UITableView)主要用来罗列展示数据项(见图),如果数据量很大,那么表格中将需要同样多的cell视图来显示,而cell的大量创建和初始化会造成内存压力,影响界面的流畅性,因此对表格视图的加载优化十分重要。UITableView的滚动优化主要在于以下两个方面:

典型表格视图

1)减少cellForRowAtIndexPath代理中的计算量(cell的内容计算)。

2)减少heightForRowAtIndexPath代理中的计算量(cell的高度计算)。

减少cellForRowAtIndexPath代理中的计算量:

①先要提前计算每个cell中需要的一些基本数据,代理调用的时候直接取出。

②图片要异步加载,加载完成后再根据cell内部UIImageView的引用设置图片。

③图片数量多时,图片的尺寸要根据需要提前经过transform矩阵变换压缩好(直接设置图片的contentMode让其自行压缩仍然会影响滚动效率),必要的时候要准备好预览图和高清图,需要时再加载高清图。

④图片的“懒加载”方法,即延迟加载,当滚动速度很快时避免频繁请求服务器数据。

⑤尽量手动Drawing视图提升流畅性,而不是直接子类化UITableViewCell,然后覆盖drawRect方法,因为cell中不是只有一个contentview。绘制cell不建议使用UIView,建议使用CALayer,因为要参考UIView和CALayer的区别和联系。

减少heightForRowAtIndexPath代理中的计算量:

①由于每次tableView进行update(更新)都会对每一个cell调用heightForRowAtIndexPath代理取得最新的height,会大大增加计算时间。如果表格的所有cell高度都是固定的,那么去掉heightForRowAtIndexPath代理,直接设置tableView的rowHeight属性为固定的高度。

②如果高度不固定,那么应尽量将cell的高度数据计算好并储存起来,代理调用的时候直接取,即将height的计算时间复杂度降低到O(1)。例如,在异步请求服务器数据时,提前将cell高度计算好并作为datasource的一个数据存到数据库供随时取用。

5.

viewDidLoad和viewDidAppear的区别是什么?正确答案:当界面第一次从xib文件或者storyboard加载界面,或者手写代码创建窗口从loadView加载界面时,才会调用viewDidLoad回调方法,而viewDidAppear方法在每次界面出现时都会调用,包括第一次加载,或者跳转离开后又跳转回来时。

从服务器加载数据的代码写在何处取决于具体需求,如果所用的数据在第一次加载后便不会再改变,那么可以在viewDidLoad中进行请求。如果界面加载后服务器数据可能会变,又必须保证当前界面的数据是最新的,那么当重新回到界面时就要重新加载最新数据,应该将数据请求代码写在viewDidAppear回调方法中。

6.

frame和bounds有什么区别?正确答案:frame是在父视图坐标系中view自身的位置和尺寸。(参照点是父亲的坐标系统)

bounds是在自身坐标系中view自身的位置和尺寸。(参照点是本身坐标系统)

7.

masksToBounds属性是什么?它有什么作用?正确答案:masksToBounds指在设置子layer在超出父layer时是否被裁剪,YES表示裁剪,NO表示不裁剪,默认是NO;通常在通过设置layer.cornerRadius属性实现圆角效果时要设置masksToBounds为YES,以保证圆角效果的实现,但这种方法是一种很低效的实现方式,也是最简单直接的。

masksToBounds和clipsToBounds是不同的,前者指子layer层在超出父layer时是否被裁剪(masksToBounds是CALayer的属性),而后者指子view在超出父view时是否被裁剪(clipsToBounds是UIView的属性)。

8.

tintColor的作用是什么?正确答案:tintColor是iOS7以后在UIView类中新增的一个属性。tintColot具有传递性,一般用来改变应用的主色调,默认为nil,表示用父视图默认的颜色进行着色。

9.

UIViewController的生命周期方法有哪些?正确答案:在开发过程中,大量的逻辑代码主要会写在UIViewController的生命周期方法中,了解这些方法的含义和调用时机十分重要。UIViewController的主要生命周期方法及其含义见表。UIViewController的主要生命周期方法及其含义方法含义[UIViewControlleralloc]创建对象并分配内存空间[UIViewControllerinitWithNibName:bundle:]视图控制器nib初始化,初始化对象以及数据[ViewControllerinit]视图控制器初始化,初始化对象以及数据-(void)loadView首次创建view调用该方法(例如首次调用view的getter方法:self.view,controller.view),如果使用了xib创建视图,那么从nib加载视图-(void)loadViewIfNeeded如果视图控制器的视图还没有加载,那么加载-(void)viewDidLoad视图加载完成,可以动态添加其他UI控件-(void)viewWillAppear:(BOOL)animated视图即将出现到屏幕上之前(每一次要显示该视图都会重复调用,不仅仅是第一次创建初始化之后,下面另外3个时机亦然)-(void)viewDidAppear:(BOOL)animated视图已经显示到屏幕上之后-(void)viewWillDisappear:(BOOL)animated视图即将从屏幕上消失(消失包括被销毁、被隐藏、被覆盖等情况)-(void)viewDidDisappear:(BOOL)animated视图已经从屏幕上消失-(void)viewWillLayoutSubviews在视图的layoutSubviews方法激活(View自身的frame发生改变)前调用-(void)viewDidLayoutSubviews在视图的layoutSubviews方法激活后立刻调用-(void)didReceiveMemoryWarning应用收到内存警告导致视图无法加载时调用,需要手动清理因为iOS6以后不会默认自动清理,通常在应用占用太大内存时被系统进行内存警告,需要在下面的viewWillUnload方法中将UI手动置nil-(void)viewWillUnload视图将不会继续加载,对应于下面的viewDidUnload,iOS6后不会再对其进行调用-(void)viewDidUnload在视图控制器被释放或者被设置为nil时调用,例如收到内存警告无法加载时,即非正常加载,而不是dealloc时的正常销毁,这里要手动清理界面元素资源;iOS6以后该回调方法被弃用了,任何情况下都不会再被调用,因为内存低时系统不再在这里清理视图元素了,官方建议之前该回调内进行的清理工作应转移到didReceiveMemoryWarning回调方法中,但实际上也并不需要再进行之前在viewDidUnload中进行的视图清理工作,系统会独立于视图单独进行处理-[UIViewControllerdealloc]视图销毁,可以释放初始化时的对象等资源

10.

View和View之间的传值方式有哪些?正确答案:以将控制器VCSource中的值传到VCTarget中为例,可以有以下6种传值方法。

1)通过视图类对象的public属性变量直接传值:可以在VCSource的头文件中定义public属性变量,这样在VCTarget中只要有VCSource的引用,即可直接访问其中的public属性变量值。

2)公有方法或代理方法的参数传值:在VCSource中调用VCTarget的公有方法并传入参数,即实现了在VCTarget中访问VCSource中的参数值;在VCTarget中实现VCSource的带参数代理方法即可获取VCSource中的值。

3)NSUserDefault简单数据存储全局共享传值:即在VCSource中存值,然后在VCTarget中将值取出进行访问使用。

4)利用通知中心NSNotificationCenter:即让VCSource向通知中心发出通知并传入参数值,同时VCTarget监听该通知从而访问VCSource传来的参数值。

5)block块传值:利用block块在视图间传值的主要应用是定义接口和回调。例如,在VCSource中定义带有block回调的对外接口方法,并将回调参数值传入block中,这样在VCTarget中调用VCSource中的该接口方法时即可在block回调中取得VCSource传来的参数值。

/*VCSource中的Login接口方法及block回调*/

+(void)Login:(void(^)(NSInteger))callback{

callback(1);

//传入围调值

}

/*在VCTarget中调用Login接口方法并访问回调参数*/

[VCSourceLogin:^(NSIntegerresult){

NSLog(@"%li",(long)result);

}];

6)extern全局变量传值:即在VCSource中定义extem全局变量暴露给外部访问。

11.

xib和storyboard相比各自的优缺点是什么?正确答案:xib优点:对UI界面的设计提供了可视化界面的功能,可以通过拖动的方式来绘制简单的UI界面,大大减少了编写UI控件的代码。

xib缺点:当界面改动较大时,需要重新添加约束:当界面复杂度较高时,xib很难实现满足需求的布局;不利于团队开发,容易造成文件冲突。

storyboard优点:能够通过可视化界面将Controller的跳转关系联系起来,还能够在Controller中进行可视化布局,大大减少了开发的代码量。

storyboard缺点:当页面很多时,会显得布局混乱,无法准确判断各个视图之间的关系;不利于团队开发,容易造成冲突。

12.

如何进行iOS6和iOS7的适配?正确答案:iOS6和iOS7的适配指iOS系统版本的适配,主要是应对iOS系统的新特性,保证同种设备不同版本的系统上能够支持相同的功能。

iOS的适配主要考虑两方面,一方面是功能上要适配兼容;另一方面是界面要适应不同分辨率的屏幕。

1)要实现功能的适配通常需要判断当前iOS系统的版本,而实现界面的适配通常需要判断当前设备的型号(屏幕分辨率)。判断iOS系统版本的方法为取UIDevice的systemVersion系统版本值来比对。

#defineiOS7[[UIDevicecurrentDevice].systemVersiondoubleValue]>=6.0

2)判断机型简单的是利用屏幕分辨率(屏幕高度)的差异性,通过屏幕高度来区分iPhone7、iPhone6或者iPhone5等。

13.

imageNamed和imageWithContentsOfFile有什么区别?正确答案:UIImage的imageNamed和imageWithContentsOfFile两种加载方法的使用如下:

/*1.根据图片文件名加载,会缓存*/

UIImage*image=[UIImageimageNamed:@"icon"];

/*2.根据文件路径加载,不缓存*/

NSString*filePath=[[NSBundlemainBundle]pathForResource:@"icon"ofType:@"png"];

UIImage*image=[UIImageimageWithContentsOfFile:filePath];

/*另外对应还有一个等效的实例方法*/

UIImage*image=[[UIImagealloc]initWithContentsOfFile:filePath];

两种方法的主要区别是使用imageNamed方法会自动缓存新加载的图片并会重复利用缓存的图片,而imageWithContentsOffile方法直接根据路径加载图片没有缓存和取缓存的过程。imageNamed先根据指定的图片资源名称在系统缓冲中搜索图片资源,找到即返回资源,找不到然后才到硬盘等地方重新加载图片资源并缓存。imageWithContentsOfFile和imageWithData类似,不会缓存图片,将图片转化成数据对象进行加载。

关于两者的选择主要考虑它们是否缓存的特点,对于那些尺寸较小且反复使用的图片资源一般会选择imageNamed方法,利用缓存加快加载速度。同时缓存太多又会占用太多空间,因此对于那些尺寸很大且不常用甚至只用一次的图片,应该选择使用imageWithContentsOfFile方法加载,不进行缓存。另外,注意imageWithContentsOfFile方法不可以直接加载Assets.xcassets图集里的图片,而需要将图片拖入工程目录。

14.

UIDevice如何获取设备信息?正确答案:iOS开发中获取设备的信息指像设备号、应用名称以及国家语言等非用户隐私信息,这些信息多数都可以在Xcode工程中看到,同时开发者可以利用框架提供的UIDevice、NSBundle、NSLocale3个类来获取一些开发中常用到的信息。

1.UIDevice

UIDevice可以提供给开发者很多移动设备的基本信息,如设备名称、设备模式、系统名称、系统版本、设备唯一标识符以及设备方向和设备电量等。

其中的设备方向是一个枚举变量UIDeviceOrientation(TV中禁止使用),源代码中的定义如下:

typedefNS_ENUM(NSInteger,UIDeviceOrientation){

UIDeviceOrientationUnknown,

UIDeviceOrientationPortrait,

//设备垂直,home键在下

UIDeviceOrientationPortraitUpsideDown,

//设备翻转,home键在上

UIDeviceOrientationLandscapeLeft,

//设备水平,home件在左

UIDeviceOrientationLandsoareRight,

//设备水平,home件在右

UIDeviceOrientationFaceUp,

//设备平放,面朝上

UIDeviceOrientationFaceDown

//设备平放,面朝下

}_TVOS_PROHIBITED;

在SDK源代码中定义如下:

@property(nonatomic,readonly,strong)NSString*name;//e.g."MyiPhone"

@property(nonatomic,readonly,strong)NSString*model;//e.g.@"iPhone",@"iPodtouch"

@property(nonatomic,readonly,strong)NSString*localizedModel;//本地化的设备模式

@property(nonatomic,readonly,strong)NSString*systemName;//e.g.@"iOS"

@property(nonatomic,readonly,strong)NSString*systemVersion;//e.g@"4.0"

@property(nonatomic,readonly)UIDeviceOrientationorientation__TVOS_PROHIBITED;//返回当前的设备方向,如果还没有产生设备方向通知(设备方向未发生改变),那么返回UIDeviceOrientationUnknown

@property(nullable,nonatomic,readonly,strong)NSUUID

*identifierForVendorNS_AVAILABLE_IOS(6_0);

//可用于唯一标识设备的一个UUID

测试示例代码如下:

/*1.UIDevice*/

UIDevice*deviee=[UIDevicecurrentDevice];

//获取当前的device

/**设备基本信息**/

NSString*name=[devicename];

//@"iPhone5S"

NSString*model=[devicemodel];//@"iPhone"

NSString*localizedModel=[devicelocalizedModel];//@"iPhone"

NSString*systemName=[devicesystemName];//@"iPhoneOS"

NSString*systemVersion=[devicesystemVersion];//@"9.3.2"

/**设备方向**/

UIDeviceOrientationorientation=[deviceorientation];

//UIDeviceOrientationUnknown

/*设备类型:iPad或iPhone(iPod)等*/

if([[UIDevicecurrentDevice]userInterfaceIdiom]==UIUserInterfaceIdiomPad|UIUserInterfaceIdiomPhone){}

/**设备电量**/

device.batteryMonitoringEnabled=YES;

floatbatteryLevel=[UIDevicecurrentDevice].batteryLevel;//0~1.0对应电量0~100%,-1.0表示电量未知

device.batteryMonitoringEnabled=YES;

/**设备ID**/

NSUUID*identifierForVendor=[deviceidentifierForVendor];

2.NSBundle

开发者经常用到类NSBundle的mainbundle,一个包含了nib文件、编译代码等资源的目录,这个目录下有一个infoDictionary,通过这个信息字典开发者可以获取有关当前应用的一些基本信息,像应用名称、应用版本等。

测试示例代码如下:

/*2.NSBundle*/

/*获取当前设备的信息字典*/

NSDictionary*info_dic=[[NSBundlemainBundle]infoDictionary];

/*本地化的信息字典*/

NSDictionary*localized_info_dic=[[NSBundlemainBundle]localizedlnfoDictionary];

NSString*app_name=[info_dicobjectForKey:@"CFBundleDisplayName"];

//应用名称@"Demo"

NSString*app_version=[info_dicobjectForKey:@"CFBundleShortVersionString"];//应用版本@"1.0"

NSString*app_build_version=[info_dicobjectForKey:@"CFBundleVersion"];//应用build版本@"1"

3.NSLocale

顾名思义,NSLocale类是用于获取一些本地化信息的,如国家、时间日期和语言等。这里主要展示常用到的获取国家和语言代码的方法。

测试示例代码如下:

/*3.NSLocale*/

/*3.1获取偏好语言*/

NSArray*languageArray=[NSLocalepreferredLanguages];

NSString*language=[languageArrayobjectAtIndex0];//@"en_HK"

/*3.2获取本

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论