ios开发知识点,简述ios的特点
iOS开发,重点iOS技术点+面试题整理
以下是我收集总结的 iOS技术点+面试题 分类;看看你都会了吗?
我们提供的服务有:成都网站设计、成都网站建设、微信公众号开发、网站优化、网站认证、天祝藏族自治ssl等。为千余家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的天祝藏族自治网站制作公司
重点总结-四大分类 :
iOS底层原理(必问) :iOS开发必备能力,也是大厂面试快速筛选人才方式之一。
常问例题 :
性能优化以及架构能力 :目前大厂对于这一块,非常重视;
常问例题:
多线程、网络能力: iOS中高级开发,都应该了解,并且熟悉的知识点;
常问例题 :
数据结构算法能力占比比较大: 通常一般大公司都会有一些笔试:虽然不在核心岗位对于数据结构算法要求不是非常严格,但是也会有一些常规的数据结构和算法的题
常问例题:
推荐阅读:iOS热门面试技术文集
iOS蓝牙开发相关知识点和注意事项
总结一下蓝牙开发相关的知识点和注意事项,做个笔记,也希望你们能少踩坑
(公司部分蓝牙项目为混编项目,蓝牙相关处理均采用了Objective-C,故本文????均采用OC,Swift处理相同)
蓝牙4.0包含两个蓝牙标准,它是一个是 双模 的标准,它包含 传统蓝牙部分(也称经典蓝牙) 和 低功耗蓝牙部分(BLE) , 二者适用于不同的应用场景和应用条件。他们的特点如下
所以蓝牙4.0是集成了传统蓝牙和低功耗蓝牙两个标准的,并不只是低功耗蓝牙
蓝牙4.0支持两种部署方式: 双模式 和 单模式 ,双模同时支持经典蓝牙和低功耗蓝牙,而单模则只支持其中一种。
二者更多细节详见: 传统蓝牙和低功耗蓝牙的区别
iOS中蓝牙相关功能都封装进了 CoreBluetooth 类中,其中有几个常见的参数和概念
具体API参考 CoreBluetooth蓝牙开发
保存到数组中的设备可通过 UUID 来进行区分。从 iOS7之后苹果不提供外设的mac地址,外设的唯一标识换成了由mac封装加密后的UUID,需要注意的是不同的手机获取同一个外设的UUID是不同的,所以在不同手机之间UUID不是唯一的,但在本机上可以作为唯一标识(特殊情况手机刷机后也会改变UUID)。
如何获取Mac地址
一般使用场景是根据Mac地址区分某个外设
注意点:
写入数据时可能会遇到需要分包发送的情况,我们可以通过下面的API或许当前特征支持的最大的单条写入长度
maxLength 一般取决于蓝牙模块内部接收 缓冲区 的大小,很多硬件设备这个缓冲区的大小是 20 字节, 这个大小也和特征的写入权限有关,像具有写入权限 withResponse 类的特征其大小一般为 512 字节,当然这些都是取决于设备测的设置;
当我们单次发送的数据字节长度大于 maxLength 时,我们就需要采用分包的方式来发送数据了,
分包发送的逻辑类似于下面
这边延时主要是设备侧的接收模块接收数据以及处理能力有限
外围设备测和中心设备(大部分情况下是手机)保持蓝牙连接的状态下,如果长时间不产生交互,蓝牙就会断开,所以为了保持两者持续的连接状态,需要做保活处理,也就是需要持续的发送心跳包(watchdog)。相应的处理是使用一个定时器定时向设备侧发送符合设备协议格式的心跳包。
断开连接很简单,只需要调用 [self.centralManager cancelPeripheralConnection:peripheral] 传入需要断开连接的设备对象就行了。断开连接时会自动调用 centralManager:didDisconnectPeripheral:error: 代理方法。
按照之前的惯例,当error为nil时表示断开成功,error不为nil时断开失败。这种理解是错误的。
当你调用 cancelPeripheralConnection: 方法(主动断开)断开连接时error为nil ; 没有调用这个方法(异常断开)而断开时error返回的是异常断开的原因。也可以理解为主动调用断开连接方法一定会断开
接下来就是断开重连的问题了,对蓝牙功能进行封装时肯定少不了断开重连。首先断开时可通过上面的代理方法的error是否为nil判断是否是异常断开,一般情况下异常断开时是需要重连的
原因就是当设备断开连接后 peripheral.services 为nil了,当然 service.characteristics 也是nil,所以需要在断开连接时把保存这个设备对应的服务和特征全部清除,然后在连接成功时重新过一遍发现服务和发现特征的流程就好了。
iOS7 开始,Apple加入了Beacon围栏检测的API, ( iBeacon-维基百科 ), 其工作方式是,配备有低功耗蓝牙(BLE)通信功能的设备使用 BLE 技术向周围发送自己特有的 ID,接收到该 ID 的应用软件会根据该 ID 采取一些行动。比如,在店铺里设置 iBeacon 通信模块的话,便可让 iPhone 和 iPad 上运行一资讯告知服务器,或者由服务器向顾客发送折扣券及进店积分, 或者公司的手机打卡,只要手机靠近打卡器一定范围,手机测就向打开器发送打卡信息,从而自动打卡。这种场景还有很多。 其中一个最重要的功能就是App的唤醒功能(杀死后也能唤醒)
举一个我们的例子,我们的产品业务场景就是在进入车辆以后,需要使用蓝牙连接我们的后装车载设备以采集车辆信息和驾驶行为行程等,这里有一个问题就是在App被杀死的情况下如何唤醒App, 因为不可能要求用户每次都主动去打开App,这样体验太差。我们的做法是通过iBeacon,当我们的车辆点火以后,设备测通电,发出 iBeacon广播 ,App实现监听iBeacon相关功能后就可以唤醒我们App,然后在相应的回调的处理一些事情,比如通过蓝牙连接设备。这里的前提条件是我们的硬件设备测包含iBeacon模块,具有iBeacon功能,而且对iBeacon的广播频率也有一定的要求,长了可能唤醒的功能会不稳定,官方建议的好像是100ms,频率超高越耗电,但可以让手机或其它监听设备越快地发现iBeacon。标准的BLE广播距离是100m,这使Beacon在室内位置跟踪场景下的效果更理想。
关于iBeacon更多的使用及介绍请参考
苹果核 - iOS端近场围栏检测(一) ——iBeacon
iBeacon技术初探
iOS 基础知识点
一、属性修饰符
读写属性: (readwrite/readonly)
语义特性:(内存有关):(assign/retain/copy)
原子特性:(和线程安全有关): (atomicit/nonatomic)
readonly:只读,属性只会生成getter方法,不会生成setter.
readwrite:既可读又可写.属性自动生成setter和getter方法.(默认的读写特性)
getter= 方法名:指定生成getter方法时的方法名.
setter= 方法名:指定生成setter方法时的方法名.
assign: 默认类型,setter方法直接赋值,而不进行retain操作,也可以只针对对象,只是做简单的赋值操作. 默认的语义特性.
retain: 针对于对象类型,setter方法对参数进行release旧值,再retain新值。
copy: setter方法进行Copy操作,与retain一样, 针对于对象类型,会拷贝一个新的对象,将新的对象的引用计数加1
nonatomic: 禁止多线程,变量保护,提高性能
atomic:原子特性,保证线程安全.系统默认的原子特性.
weak:指针指向的地址一旦被释放,这些指针都将被赋值为nil。这样的好处能有效的防止野指针。消除循环引用 。
二、 @dynamic 关键字
@dynamic dynamicStr; // 告诉编译器,不自定生成getter和setter方法,避免编译期间产生警告,然后由自己实现存取方法。
三、 @synthesize 关键字
@synthesize strongStr = _strongStr; // 可以定义 与变量名不相同的getter和setter的命名,籍此来保护变量不会被不恰当的访问, 编译器期间,让编译器自动生成getter/setter方法 当有自定义的存或取方法时,自定义会屏蔽自动生成该方法
四、重定义setter方法getter方法
// 重定义setter方法
// 重定义getter方法
五、不可变字符串 NSString
// 运行log日志:
2021-03-11 17:30:08.112340+0800 TestObject-C[93449:1623723] temp1: 不可变字符串, 0x10df9e778
2021-03-11 17:30:08.112529+0800 TestObject-C[93449:1623723] str: 不可变字符串, 0x10df9e778
2021-03-11 17:30:08.112610+0800 TestObject-C****[****93449:1623723****]**** strongStr: ****不可变字符串****, 0x10df9e778
六、可变字符串 NSMutableString
// 一、将不可变字符串赋值给可变字符串对象。
// 赋值可变字符串对象后,对象仍然是不可变对象
2021-03-11 17:30:08.114159+0800 TestObject-C[93449:1623723] mTemp: 不 可变字符串1, 0x10df9e878
2021-03-11 17:30:08.114393+0800 TestObject-C[93449:1623723] mCopyStr: 不 可变字符串1, 0x10df9e878
2021-03-11 17:30:08.114697+0800 TestObject-C****[****93449:1623723****]**** mStrongStr: 不 可变字符串****1, 0x10df9e878
// 一、将可变字符串赋值给可变字符串对象。
2021-03-11 19:38:34.493763+0800 TestObject-C[95274:1718783] mTemp2: 可变字符串2, 0x600002710ea0, __NSCFString
2021-03-11 19:38:34.493923+0800 TestObject-C[95274:1718783] mCopyStr: 可变字符串2, 0x6000027110e0, __NSCFString
2021-03-11 19:38:34.494037+0800 TestObject-C****[****95274:1718783****]**** mStrongStr: ****可变字符串****2, 0x600002710ea0, __NSCFString
2021-03-11 19:38:34.494422+0800 TestObject-C[95274:1718783] mTemp2: 可变字符串211, 0x600002710ea0, __NSCFString
2021-03-11 19:38:34.494697+0800 TestObject-C[95274:1718783] mCopyStr: 可变字符串2, 0x6000027110e0, __NSCFString
2021-03-11 19:38:34.494903+0800 TestObject-C****[****95274:1718783****]**** mStrongStr: ****可变字符串****211, 0x600002710ea0, __NSCFString
七、富文本字符串 NSMutableAttributedString
2021-03-11 19:34:52.041131+0800 TestObject-C[95207:1715249] attriStr: 我是富文本我是富文本我是富文本我是富文本, 0x600000a5bc00, NSConcreteMutableAttributedString
2021-03-11 19:34:52.041307+0800 TestObject-C[95207:1715249] mutableAttri: 我是富文本我是富文本我是富文本我是富文本, 0x600000a5be40, NSConcreteAttributedString
2021-03-11 19:34:52.041425+0800 TestObject-C****[****95207:1715249****]**** mutableStrongAttri: ****我是富文本我是富文本我是富文本我是富文本****, 0x600000a5bc00, NSConcreteMutableAttributedString
2021-03-11 19:34:52.041943+0800 TestObject-C[95207:1715249] attriStr: 我是富文本我是富文本我是富文本我是富文本---我是新添加的, 0x600000a5bc00, NSConcreteMutableAttributedString
2021-03-11 19:34:52.042281+0800 TestObject-C****[****95207:1715249****]**** mutableStrongAttri: ****我是富文本我是富文本我是富文本我是富文本****---****我是新添加的****, 0x600000a5bc00, NSConcreteMutableAttributedString
八、不可变数组NSArray
//一、 不可变数组赋值NSArray的对象
2021-03-11 19:04:42.636207+0800 TestObject-C[94739:1689350] arr: (1, 2,
3), 0x600001d5c8d0
2021-03-11 19:04:42.636411+0800 TestObject-C[94739:1689350] persons: ( 1, 2, 3), 0x600001d5c8d0
2021-03-11 19:04:42.636538+0800 TestObject-C[94739:1689350] students: (1, 2, 3), 0x600001d5c8d0
2021-03-11 19:04:42.636646+0800 TestObject-C[94739:1689350] arr: (1, 2, 3), 0x600001d5c8d0
2021-03-11 19:04:42.636767+0800 TestObject-C[94739:1689350] students: (1, 2,3), 0x600001d5c8d0, __NSArrayI
// 二、不可变数组赋值给NSMutableArray的对象
**2021-03-11 19:15:59.046728+0800 TestObject-C[94934:1699039] arr: (1,2,3), 0x600002f6c000
2021-03-11 19:15:59.046878+0800 TestObject-C[94934:1699039] cars: (1, 2,3), 0x600002f6c000, __NSArrayI2021-03-11 19:15:59.046982+0800 TestObject-C[94934:1699039] dogs: (1,2,3), 0x600002f6c000, __NSArrayI
九、可变数组 NSMutableArray
2021-03-11 19:22:39.183745+0800 TestObject-C[95044:1705082] arr2: (2,4,10,12), 0x600000fefea0
2021-03-11 19:22:39.184067+0800 TestObject-C[95044:1705082] cars: (2,4,10), 0x600000fef240, __NSArrayI
**2021-03-11 19:22:39.184272+0800 TestObject-C[95044:1705082] dogs: (2,4,10,12), 0x600000fefea0, __NSArrayM
十、不可变字典 NSDictionary
// 不可变数组赋值给NSDictionary对象
2021-03-11 19:25:32.789615+0800 TestObject-C[95102:1708378] dic: {key1 = 1;key2 = value;}, 0x6000028799c0**
2021-03-11 19:25:32.789801+0800 TestObject-C[95102:1708378] personDic: { key1 = 1;key2 = value;}, 0x6000028799c0, __NSDictionaryI
2021-03-11 19:25:32.789919+0800 TestObject-C[95102:1708378] studentDic: { key1 = 1;key2 = value;}, 0x6000028799c0, __NSDictionaryI
十一、可变字典 NSMutableDictionary
2021-03-11 19:59:28.739545+0800 TestObject-C[96373:1735182] mDic: { key1 = 10;key2 = value2;}, 0x6000017f0700, __NSDictionaryM
**2021-03-11 19:59:28.740177+0800 TestObject-C[96373:1735182] carDic: {key1 = 10;key2 = value2;}, 0x6000017f07a0, __NSFrozenDictionaryM
2021-03-11 19:59:28.740359+0800 TestObject-C[96373:1735182] dogDic: { key1 = 10;key2 = value2;}, 0x6000017f0700, __NSDictionaryM
2021-03-11 20:05:24.028840+0800 TestObject-C[96469:1740141] mDic: {key1 = 10; key2 = value2;key4 = value4;}, 0x6000011bd7e0, __NSDictionaryM
2021-03-11 20:05:24.028930+0800 TestObject-C[96469:1740141] carDic: { key1 = 10; key2 = value2;}, 0x6000011bd820, __NSFrozenDictionaryM
2021-03-11 20:05:24.029028+0800 TestObject-C[96469:1740141] dogDic: {key1 = 10;key2 = value2;key4 = value4;}, 0x6000011bd7e0, __NSDictionaryM
十二、不可变集合 NSSet
// 一、不可变NSSet赋值给 NSSet对象
2021-03-11 20:09:49.418694+0800 TestObject-C[96545:1744249] set: {( 1,2,3)}, 0x600003fd2e80, __NSSetI
2021-03-11 20:09:49.418826+0800 TestObject-C[96545:1744249] personSet: {(1,2,3)}, 0x600003fd2e80, __NSSetI
2021-03-11 20:09:49.418914+0800 TestObject-C[96545:1744249] studentSet: {(1,2,3)}, 0x600003fd2e80, __NSSetI
// 二、不可变NSSet赋值给 NSMutableSet对象
2021-03-11 20:09:49.419281+0800 TestObject-C[96545:1744249] carSet: {(1,2,3)}, 0x600003fd2e80, __NSSetI
2021-03-11 20:09:49.419362+0800 TestObject-C[96545:1744249] dogSet: {(1, 2,3)}, 0x600003fd2e80, __NSSetI
十三、可变集合 NSMutableSet
2021-03-11 20:18:06.896997+0800 TestObject-C[96705:1752827] mSet: {(3,1,2,5)}, 0x600001e0a700, __NSSetM
2021-03-11 20:18:06.897218+0800 TestObject-C[96705:1752827] carSet: {( 1,2,3)}, 0x600001014bd0, __NSSetI
2021-03-11 20:18:06.897340+0800 TestObject-C[96705:1752827] dogSet: {(3,1,2, 5)}, 0x600001e0a700, __NSSetM
iOS开发之基础篇(5)—— NSNumber、NSValue
Xcode 8.2.1
前文说过,NSArray和NSDictionary只能存入OC对象。不信我们可以做个试验:将一个int类型或者是NSInteger放入NSMutableArray里面。(NSInteger和int的差别:NSInteger会根据系统的位数32or64,自动选择int的最大数值int or long,这样我们就不用考虑设备是32位还是64位系统)
这样是会编译出错的,存入不成功。
那怎么办呢?所以,我们需要将int或者NSInteger类型转换成NSNumber(OC对象),然后再存入NSArray中。
NSNumber可以转换一系列的基础数字类型(char、int、float、long、bool等等),还提供了一个compare方法来将NSNumber对象进行数值排序。
我们来看看NSNumber有哪些要掌握的知识点:
运行结果如下:
之所以把NSNumber和NSValue放到同一篇,是因为NSNumber是NSValue的子类,NSValue除了能够包装NSNumber能够包装的基础数字类型外,还能够包装系统框架提供的CGRect/CGPoint/CGSize等数据结构,也可以是自己定义的struct。最终也能放入数组。
同样,我们来看看它的应用:
运行结果:
标题名称:ios开发知识点,简述ios的特点
文章转载:http://cdiso.cn/article/dsdgsgo.html