声明:本篇博文是作者原创作品。参考1 参考2 参考3 参考4 参考5 参考6
关于网上一些关于iOS资料,自己通过学习做了一些整理,这里仅仅作为笔记,方便自己学习使用,加深理解。
1.什么是 Handoff ? 参考
Handoff 使用前要保证,手机 和 电脑在同一局域网下(连接同一个WiFi),首先要在电脑(iCloud)和手机上登陆你的苹果ID,然后手机上开启 Handoff 在 电脑的 Dock 上会看到有一条来自于 ***IPhone 的邮件,这样就将手机与电脑进行了连接,为什么要这样做呢?也许苹果考虑到苹果手机屏幕太小,有苹果电脑的用户可以通过这种连接,在大的屏幕上操作较小屏幕的设备。
2.iCloud包含了那些技术与服务?参考
是苹果的一项云端技术,使用者可以免费试用5G的存储空间,可以用来存储照片、通讯录、短信、文档等内容,在需要的时候以无线的方式将他们推送到设备上,使用者可以从任何的计算机上、任何设备上随时方便的进行访问iCloud上所提供的应用程 序包括办公生产率、开发工具、媒体和窗口小部件等。
3.iOS的扩展是什么?举一些常见的例子?
扩展是为一些可见源代码的类或者不可见源代码的类添加一些编程人员要使用到的方法,我们在某一个框架中要为某一个类添加方法,可以为该类添加一个扩展方法,这样我们就不需要再为该类写一个子类去继承了,提高了效率。在不为该类赠加子类的前提下,为该类添加了方法接口,但是注意只能够添加方法,不能够添加实例变量。
4.OC是如何对内存进行管理的,ARC和MRC的内存管理区别在哪里?
OC 采用了引用计数的方法对内存进行管理。
5.协议与类别?
协议是一组方法的声明,不需要实现,可以由任何类去实现,但是该类必须遵循该协议,可以说协议就是一组接口,由其他的类去实现。要实现接口的类,必须遵守声明接口的协议。
类别是为可见源代码、不可见源代码的类的扩充,但是不能为其增加私有的属性字段,只能扩充方法,不能扩充实例变量。我们在为一个已经存在的类增加方法的时候,不需增加一个子类,很方便。
6.(委托)代理有什么作用?代理怎么实现,简单的代码举例?
委托就是一个对象要实现的事情让另一个对象去实行,委托方要制定一系列的协议,执行方要去遵循这些协议去实现委托方要求实现的的事情,代理需要遵循协议,并且在委托方下达命令的时候去执行任务。
假设有两个类A、B。
A制定协议,并在A类中声明一个协议的属性,id<Adelegate>delegate;
声明实例对象 A * a = [[A alloc] init]; B * b = [[B alloc] init]; 设置代理对象 a.delegate = b;
B类要遵循协议,B<Adelegate>,在B中 b 去实现协议中的方法;
类 A在合适的时候让 B去执行任务,A下达命令让B去做事情;
7.描述一个 retain cycle 的例子?
在该类中定义了代理的属性,属性的语义属性为 retain ,在代理对象类中也定义了属性去存储该类的对象,语义特性也为 retain,这样就会造成循环引用。
在A类的对象定义的时候属性语义为 retain,B类的对象定义的时候语义属性也为 retain ,在 A类中使用 B类的对象,在B类中使用 A类的对象,就会造成循环引用。
8. #import 与 #include 与 @class 在使用的时候有什么区别?
9.在一个对象的方法里面加上 self.name = @"object" 与 _name = @"object" 有什么区别?
self.name = @"object"是调用属性生成的一个 setter 方法,在走setter 方法的时候,会首先判断该对象与之前的_name 是否一致,如果不一样,就讲原来的_name ,release 掉,然后再将该对象 retain ,引用计数加 1 ,获得对该对象的拥有权。
后者是仅仅对该对象的简单赋值,存储一下内存地址,该实例变量的引用计数并不加1.
10. self.name = nil 与 [_name release]的区别?
前者是调用了一下属性的setter 方法,现将自身 release 引用计数减1,然后在再将该对象的值置空,以后再访问该实例变量不会出现任何的内存问题。
后者仅仅是简单的将该对象的引用计数减1,并没有对该对象的内存中存储的值置为空,这样指针变量中依然存有该对象的内存地址,当系统回收该对象的内存的时候,在去访问该对象,就会出现野指针异常。
11.定义一个标准的宏定义,这个宏定义输入两个参数,返回一个较小的数?
//实现一个宏定义,输入两个参数,返回一个较小的参数
/*方法1*/
#define MINSIMPLE(A,B) ((A)<=(B)?(A):(B))
/*方法2*/
#define kMin(A,B) ({__typeof__(A) a=A;__typeof__(B) b = B;a < b ? a :b})
/*方法3*/
#define __NSX__PASTE__(A,B)A##B
#define __NSMIN__IMPL__(A,B,L)({__typeof__(A)__NSX_PASTE__(__a,L)=(A);__typeof__(B)__NSX_PASTE__(__b,L)=(B);(__NSX_PASTE__(__a,L)<__NSX_PASTE__(__b,L))?__NSX_PASTE__(__a,L):__NSX_PASTE__(__b,L);})
#define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__)
12.__typeof 与 typeof 的区别?
现在iOS7建议我们使用 typeof 不建议我们使用 __typeof ,typeof 关键字是C语言的一个新的扩展,这个特性在Linux内核中用处非常广泛,typeof 的参数可以是两种形式:表达式、类型。
13.下进程与线程的区别?
线程是进程内的一块执行单元,也是执行任务的基本单位,从以下方面比较他与进程的区别:
(1).从地址空间上:线程是进程内的一个执行单元,进程至少有一个线程,这些线程共享进程的地址空间,而进程有自己独立的地址空间。
(2).从资源的拥有上:进程是资源分配和拥有的单位,同一个进程内的线程共享进程的资源。
(3).线程是操作系统处理调度的基本单位,但是进程不是。
14.解释一下iOS的沙盒机制?
iOS的沙盒机制是一种安全的体系,它规定了应用程序只能在为该应用创建的文件夹内读取文件,不可以访问其他地方的内容。所有的非代码文件都保存在这个地方,比如:声音、图片、属性列表、文本文件等。
沙盒机制要遵循以下原则:
(1).每一个应用程序都在自己的沙盒内。
(2).每一个应用程序都不能够跨过自己的沙盒去访问其他的应该用程序的沙盒内的内容。
(3).应用程序向外请求数据或者接受数据都要经过权限的认证。
15.OC中的数字对象有哪些,简述他们与基本数据类型的区别?
在OC 中的数字对象有 NSValue NSNumber 两种。
NSValue 是OC 中的对象类型, 能够实现将结构体类型 CGPoint、NSRange 转化成OC对象。
NSNumber 是 OC 中的对象类型,能够将基本的数据类型转化为 OC 对象,如:float、int、double。
16.swift 与 oc 相比两者有什么区别,有什么联系?
17.总结一下编程书写代码格式的注意事项?
(1).变量名要严格的遵循英语,做到见名知意,而不应该去遵循汉语拼音去实现见名知意。
(2).方法之间要用一行空格去隔开,方法内部的空白应该起到隔离单独的功能实现,一般单独的功能都是抽出来作为一个方法。
(3).对于方法的对齐格式,Block不要用冒号对齐的格式,但是其他情下还是可以用冒号的对齐书写的格式。
(4).注释的时候,要简明了当,尽量不要块注释,建议使用自注释
(5).在方法签名中,应该在方法类型(-/+ 符号)之后有一个空格。
(6).定义类的名字的时候,要尽量的在前面添加特殊意义的前缀(比如公司名字的缩写),目的是防止与一些第三方SDK的名字有重复,也不要与Xcode 系统的类名字重复。
(7).再设计接口的时候,接口的名字尽量的不要使用缩写,但是这些常用的缩写除外(alloc,init)在设计参数名的时候可以使用缩写。
(8).代码命名规范。
a.要清晰、简洁,如果无法两全的时候要尽量的保证清晰,就是要避免难以理解、歧义的去命名。即便很长的名字我们也要去完整的拼写方法名字。不要自认为某些缩写众所周知,因为可能仅仅是你自己知道,但是可以写一些重所周知历史悠久缩写。对于API命名的时候,要避免歧义。
b.在遇到疑惑的情况下要去查询当前的头文件或者参考文档,当某个类方法使用了多态的时候,一致性很重要;不同的类里,功能相同的方法命名也应相同。
c.命名要避免自引用,如对于字符类型的命名时,NSString 是正确的,但是 NSStringObject 是不规范的。注意:Mask 与 Notification 忽略此规则。
d.前缀是声明API的重要组成部分,他们区分了软件不同功能区域。
前缀可以很有效的防止与Apple的命名冲突;
前缀可以防止与Apple内部的命名冲突;
前缀要有指定的格式;一般由2-3个大写字母组成,不使用下划线和子前缀;
命名类、协议、函数、常量和 typedef 结构体时使用前缀;
方法名不使用前缀,因为它存在于特定的命名空间中;结构体字段不使用前缀。
f.书写约定:
在定义一个API的时候,要遵循驼峰命名法则,第一个字母小写,以后每一个单词的首字母都要大写,如果方法名字以一个众所周知的大写缩写开始,则不能使用该规则。如TFFRepresentation(NSmage);
函数与常量名字,使用其关联类相同的前缀,并大写首字母。如:NSCellDisabled;
标点符号:由多个单词组成的名称,不要使用标点符号做为名称的一部分,分割符号(下划线,破折号)也不能使用。
不要使用下划线做为私有方法的前缀,Apple保留这一方式的使用,如果你要强行的使用则有可能会导致与系统的方法冲突,这样覆盖了系统方法,将会导致无法估量的灾难后果。但是实例变量的下划线作为其前缀还是允许的。
在声明类的时候,class的名称要包含一个名词,用来表明该类的作用是什么(或者做了什么),并有合适的前缀。如NSString、NSDate等等。
对于不关联的 class 与 protocol: 大多数的peotocol 聚集了一堆相关方法,并不关联 class, 可以在 protocol 中使用 ing 的形式来和 class 区分开来。
对于关联的 class 与 protocol: 一些protocol聚集了一堆无关联的方法,并试图与某个class关联在一起,由这个 class 来主导,这样的 protocol 与 class 同名,如 PersonDelegate。
g.头文件注意规范
暂时觉得其描述的过于抽像,没有理解,稍后添加自己的理解。《****》
h.方法的书写注意
以小写字母开始,以后的单词首字母要大写。
以众所周知的缩写开始可以大写,如:PDF。
私有的方法可以添加前缀。
如果方法代表的对象以接受的动作,以动词开始。
不要使用do或者 dose 的一类很少有实际意义的助动词。同样在动词前也不要使用副词和形容词。
如果方法返回接受的属性,以 接受者 + 接收的属性 命名。除非返回多个值,否则不要使用 get 单词。《****》
在所有的参数之前使用关键字,表明该参数的类型。
在创建init方法的时候,要说明关联的元素,不要使用 and 来连接作为接收者属性的关键字,要使用 with,也可以不适用连接词,直接“:参数1 :参数2”。但是在方法描述了两个独立的操作的时候,则可以使用 and 来连接他们。
如果属性中出现动词,动词要用一般现在时,不要将动词的过去分词形式当做形容词使用,可以使用情态动词 can ,will ,should 但是不要使用 do,dose,只有方法在一些情 况下要返回多个参数的时候才使用 get。
在代理的方法声明中,如果参数有两个或者两个以上,则参数可以省略类名的前缀并且小写该参数,但是不适合 - (BOOL)applicationOpenUntitledFile:(NSApplication *)sender; 和 - (
void
)windowDidChangeScreen:(NSNotification *)notification; 前者只有一个sender参数的方法,后者响应notification的方法(方法的唯一参数就是notification)。询问delegate是否可以执行某个行为时可以使用 did 或 will,不过 should 更完美。
对于集合中的一些方法,如果集合是无序的,则返回一个NSSet比 NSArray 更好。
对于方法参数,要避免使用1-2个字母为方法名,不要使用 "pointer", "ptr"命名,因为参数类型中“*”就表明了他的类型,也要避免只有几个字母的缩写。
如果继承大型的框架,请保证子类的私有方法与父类的方法名字不一样,否则就会重写父类的方法实现。
i.宏定义的规范
不要使用#define预编译指令来创建常量,integer常量使用枚举,float常量使用 const 修饰符;
对于#define 的预编译指令,大写所有的字母,如 DEBUG 判断
注意宏命令的首字母和尾字母都有双下滑线。__MINVALUE__
定义NSString 常量作为通知和 key 的值。
j.函数的命名注意
函数命名类似方法,但是要注意:使用的类和常量有相同的前缀,前缀后的首个字母要大写。
许多函数名以描述其作用的动词开始。
查询属性的函数有进一步的命名规则:如果函数返回首个参数的属性,省略动词;如果通过reference返回了值,使用 “Get”;如果返回的是boolean值,应该灵活使用动词 。
k.对于通知的书写规范
[Name of associated class]
+ [Did | Will] + [UniquePartOfName] + Notification
l.对于延展的书写格式规范
[Prefix] + [UniquePartOfName] + Exception
m.实例变量命名规范
通常不应该直接访问实例变量
init、dealloc、accessor methods等方法内部例外
实例变量以下划线 “_” 开始
确保实例变量描述了所存储的属性@implementation MyClass{
BOOL
_showsTitle;
}
如果想要修改property的实例变量名,使用 @synthesize语句@implementation MyClass
@synthesize showsTitle=_showsTitle;
为一个class添加实例变量时,有几点需要注意:
避免声明公有实例变量
开发者关注的应该是对象接口,而不是其数据细节你可以通过使用property来避免声明实例变量
如果需要声明实例变量,指定关键字@private 或 @protected 如果让子类可以直接访问某个实例变量使用 @protected 关键字
如果一个实例变量是某个类可访问的属性,确保写了accessor methods如果有可能,还是使用property。