原创:知识点总结性文章
创作不易,请珍惜,之后会持续更新,不断完善
个人比较喜欢做笔记和写总结,毕竟好记性不如烂笔头哈哈,这些文章记录了我的IOS成长历程,希望能与大家一起进步
温馨提示:由于简书不支持目录跳转,大家可通过command + F 输入目录标题后迅速寻找到你所需要的内容
目录
- OC语言
- Swift语言
OC语言
- 在命名类时使用前缀命名可以保证类名唯一,两个字母的前缀NS和UI被苹果公司保留使用
- APP 来说最好的用户体验是隐蔽地从错误中恢复
-
import
优于include
的地方在于不会导致重复引入头文件, 不存在嵌套引用的问题 -
NSError
对象包含一个数字错误代码,域名和描述,以及封装在一个用户信息字典里的其他相关信息 -
NSNull
用于在集合中作占位符,NSNull
是单例对象,全局只能有一个(设备管理类)NSNull *null = [NSNull null];
如果你需要在集合中表示“没有对象”,你要使用NSNull
代替nil
- 加入集合中的每一个对象的生命周期都将至少和集合的生命周期一样长
-
NSValue
是NSNumber
基类,除了 C 的基本纯量类型,NSValue
也可以表示指针和结构体 -
Number
实际上是一个类集。这意味着当你在运行时创建了一个实例时,你会得到一个合适的具体化的子类,值为给定值 - 通常会在公共接口中将一个属性定义为只读,而在实现代码的上方的类扩展中将其定义为读写。这是为了让内部方法可以直接修改属性值
- 如果对于一个可读写的属性同时手动实现了存取方法,或对于一个只读属性实现了取方法,那么编译器就会认定读者接管了属性的实现,不会自动合成实例变量
- 属性默认是多线程的, 可以使用
nonatomic
单线程特性来明确编译器自动合成的存取方法只单纯设置或返回一个值,如果同一个值同时被多个线程访问,可能会发生意外。 -
@synthesize firstName = ivar_firstName;
属性名仍然为firstName
,而且可以通过firstName
和setFirstName
的存取方法以及点语法访问,但其背后运行机制中的实例变量的名称将为ivar_firstName
- 如果读者直接使用
@synthesize +
属性名,其后不加任何实例变量名,例如@synthesize firstName;
那么实例变量将会和属性名同名,没有下划线 - 读取属性时使用
somePerson.firstName
就等同于使用[somePerson firstName]
设置属性时使用somePerson.firstName = @"Johnny"
就等同于使用[somePerson setFirstName:@"Johnny""]
- 把数值类型的实例变量初始化为0,id 和其他类型的指针变量也会被初始化为nil。对于返回值类型为对象的消息来说,其返回值为nil;数字类型的是0;布尔类型的是NO;结构体类型的全部结构成员都会被设置为0;
-
==
用来判断两个不同的指针是否指向同一个对象,isEqual
用来判断是否代表相同的数据值 -
init
方法有可能返回一个同alloc
方法所创建的对象相比完全不同的对象,所以最好的方法是将两个方法嵌套发送。工厂方法是内存分配和初始化这一过程的另一种选择,或者使用简便字面量语法创建对象,这样就不用再嵌套两个方法 - 如果要使用全局变量,那么其名称在整个应用或者项目中必需唯一
- 不要在自定义
get
和set
方法中使用点语法,否则造成方法递归死循环 - 成员变量放在
interface
里默认是@protected;
,放在implementation
,默认是@private
- 不要滥用自动释放池,因为自动释放池只有在它销毁时候才会对它管理的对象做释放,如果程序中创建了大量对象,这些对象得不到有效及时释放
-
retain
是浅复制,copy
是深复制,字符串对象一般使用copy
,而不用retain
,防止字符串改变导致的连锁反应 - 自定义对象如果要支持
copy
操作,必须实现copywithzone
方法, 遵从<NSCpoying>
协议 -
stop
提供了对遍历的控制,想要让遍历过程停止的时候,将它设置为YES -
NSSet
使用散列表(hash table)
的技术存储对象,不是连续存储, 相同值只能有一个 - 编译时之所以没出错,是因为编译时无法确定存储在
id
中的对象的类型,动态绑定 - 消息选择器和参数和返回值的类型信息息结合起来构成签名
(signature)
- 没指定
nonatomic
的时候,访问方法中需要使用lock
和unlock
来保证方法的原子性,每次最多有一个线程执行lock
和unlock
之间的代码。对使用频繁且不用考虑多线程竞争的访问方法,可以在声明的时候加上nonatomic
-
@synthesize
能自动生成和接口文件中声明的属性一致的访问方法。@dynamic
自动合成无效, 用户会自已生成属性的getter
和setter
方法,@dynamic
是可选的 - 类的前置声明:引入的头文件中还有可能还引入了其他类的头文件,如此循环会大大加大编译时的负担
- 类仅能生成一个实例,程序中访问到这个类的对象时使用的都是同一个实例对象。在设计模式中这种清况称为单例模式(
singleton
),例如控制程序运行的NSApplication
。这些类通过以shared
开头的类方法返回唯一的实例对象 - 实际的复制操作并不是由
copy
来完成的.而是由实例方法copyWithZone:
完成的,需要满足协议NSCopying
将对象打包成二进制文件就称为归档(archive
),可以使用NSKeyedArchiver
和NSKeyedUnarchiver
完成对象的归档和解档操作,需要遵循协议NSCoding
-
xib
文件为XML
格式文件, 在应用被构建的问时,Storyboard
内部也会变为nib
文件资源 - 属性列表中实际的键值和Xcode 中表示的字符串有时是不同的。例如,之前所述的键
CFBundleldentifier
可能就会被表示为"Bundleindentifier"
,为表示键值原本的意思,在Xcode 中, 可以右击并选择上下文菜单中的"Show Raw Keys/Values"
- 枚举类型有一个很大的作用,就是用来代替程序中的魔法数字
- 如果是懒加载的话则一定要注意先判断是否已经有了,如果没有那么再去进行实例化
- 使用
performSelector:
是运行时系统负责去找方法,在编译时候不做任何校验;因此在使用时必须先使用respondsToSelector:
检查对象是否能调用方法,否则可能出现运行崩溃 - OC中可以用点语法直接调用方法,但是有一个前提条件就是该方法调用不需要传参,这也是在
Masonry
框架中链式语法的主要原因 - 使用
@class
仅仅是告诉编译器这是一个类,并不会因入该类的其他信息,可以提升编译性能。为了避免两个类之间循环引用,我们在某一个类的.h
文件中用@class
进行导入,一个用#import
一个用@class
,或者两个都用@class
都可以避免报错。 -
self.xx
是调用的xx
属性的get/set
方法,而_xx
则只是使用成员变量_xx
,并不会调用get/set
方法 - 如果点表达式出现在等号
=
左边,调用该属性名称的setter
方法。如果点表达式出现在=
右边,调用该属性名称的getter
方法。 - 实际上返回的是子类的实例,这一系列的类被称为一个类簇
(cluster)
,这个父类就模拟了抽象类的功能 -
PCH文件(Precompile Prefix Header File)
,也就是预编译头文件,其作用就是,方便你一次性导入在多个文件中同时用到的头文件、宏或者URL地址等(全局使用),可以有效的帮你节约时间,提高开发效率 -
plist
只能放在根目录下,否则报错 - 给父类
view
添加透明度子类也变得透明,用如下方式给父类view
设置透明度不要使用alpha
设置self.backgroundColor = [[UIColor lightGrayColor] colorWithAlphaComponent:0.5];
- 函数结构在百行内,太多逻辑结构就忘了。常量防止拼写错误系统补全,多处使用。
-
@synthesize
用在实现文件中告诉编译器实现成员变量的的访问器(getter/setter)
方法, 这样的好处是:免去我们手工书写getter
和setter
方法繁琐的代码。@synthesize age = _age;
-
objc_msgSend
会通过判断self来决定是否发送消息,如果self
为nil
,那么selector
也会为空,直接返回,不会出现问题。向nil
发消息可能会返回nil
(返回值为对象),0(返回值为一些基础数据)但对于[NSNull null]
对象发送消息时,是会crash
的,因为NSNull
类只有一个null
方法。 - 同一个
UIButton
可以多次addTarget:
添加事件,前面添加的并不会失效, 两次添加的事件均可执行,互不影响。事件执行的顺序为添加事件的顺序。 -
UIViewController
视图控制器、UIApplication
都继承自UIResponder
。 -
Storyboard
事实上是由XML
可扩展标记语言构成的文本文件
-XCTest
框架可以进行单元测试,但是无法进行性能测试。Xcode的UI测试功能能够自动记录你在应用程序界面中的每一个操作步骤, 它可以将每一步的操作自动生成对应的代码。 - Git和SVN等其它版本控制系统的一个重要不同之处,就是Git有暂存区
- Git版本控制有哪三种状态:
committed
、modified
、staged
-
Instruments
中的Allocations
工具,可以显示内存中的对象占用曲线,内存当前分配给了哪些对象,被分配内存的对象数量,以及由哪些函数进行对象的创建。 - GCD的API很大程度上是和以下哪种技术配合使用的?
block
-
Thread
多线程技术是基于什么来实现多线程的?Thread
线程 -
Operation
多线程技术是基于什么来实现多线程的?Queue
队列 -
Grand Central Dispatch
多线程技术是基于什么来实现多线程的?Task
任务 - 死锁有哪些必要条件? 互斥、请求保持、不可剥夺、循环等待
- 根类和根类协议:
NSObject
不但是个类名,NSObject
也是个协议的名称。根类的主要方法:分配、初始化、复制。 - 分配:
alloc
和allocWithZone:
方法用于从某内存区域中分配一个对象内存,并使对象指向其运行时的类定义。 - 初始化:
init
方法是对象初始化。new
是一个将简单的内存分配和初始化结合起来的方法。 - 复制:
copy
和copyWithZone
-retain
方法增加对象的保持次数。release
方法减少对象的保持次数。autorelease
方法也是减少对象的保持次数,但是以推迟的方式。retainCount
方法返回对当前的保持次数。 -
dealloc
方法由需要释放对象的实例变量以及释放动态分配的内存的类实现。
-isKindOfClass:
和isMemberOfClass:
方法来确定对象属于哪个类。后者用于测试接收者是否为指定类的实例。isSubclassOfClass:
类方法则用于测试类的继承性。 -
respondsToSelector:
方法用于测试接收者是否实现由选择器参数标识的方法。instancesRespondToSelector:
类方法则用于测试给定类的实例是否实现指定的方法。 -
conformsToProtocol:
方法用于测试接收者(对象或类)是否遵循给定的协议。 -
description
方法允许对象返回一个内容描述字符串;这个方法的输出经常用于调试(“print object”命令)
,以及在格式化字符串中和“%@”
指示符一起表示对象。 -
encodeWithCoder:
和initWithCoder:
是NSCoding
协议仅有的方法。前者使对象可以对其实例变量进行编码,后者则使对象可以根据解码过的实例变量对自身进行初始化。 - 对元素均为
strong
引用, 集合持有关系,不是存副本拷贝 - 集合类型常规
copy
均为浅copy
-
copyItems
=YES
,deep copy
,会给每一个元素发送copy
消息 - 数组会给其中的所有对象发送
retain
消息。当数组被释放的时候,它会给数组中的所有对象发送release
消息 - 字典没有越界问题,有值就返回
- 字典基于
Hash map
映射机制,hash
值唯一 -
key
和Value
必须是对象类型 不能是bool
、int
- 字典的
key
必须为NSObject
且遵循NSCopying
协议 -
NSNumber
遵循NSCopying
/NSSecureCoding
协议 -
NSData
、NSString
遵循NSCopying
/NSMutableCopying
/NSSecureCoding
协议 -
immutable
对象的copy
,会直接返回自身(优化手段) -
immutable
对象的mutableCopy
,会返回一个mutable
副本 -
mutable
对象的copy
,会返回一个immutable
副本 -
mutable
对象的mutableCopy
,会返回一个mutable
副本 -
mutableClass
为immutableClass
子类, 具备添加,删除,替换等功能, 自身可变,无需返回新实例 -
Move to Trash:
可以彻底删除 文件,而Remove References
按钮只是从工程中删除文件 - 一个工程中可以包含多个目标,一个目标包含了一些源程序文件、资源文件和编译说明 文件等内容,其中编译说明文件通过“编译参数设置"
(Build Settings)
和"编译阶段"(Build Phases)
设置,目标可以覆盖工程的设置 - 要指定运行哪一个目标,可以通过选择不同的方案
(Scheme)
来实现 -
Auto Layout
解决布局问题,而SizeClass
解决屏幕适配问题。 - 状态栏占用20点——导航栏占用44点——标签栏占用49点,导航栏、工具栏、搜索栏、搜索范围栏和表视图单元格等的高度都是44点。
-
Horizontally in Container
, 后面的 数字是与中间轴的偏移量 ,设置为 0表示刚好居中 - 虚线线段代表相对距离,实线线段代表绝对距离,点击可以相互切换
- 看到该约束被加粗和添加阴影显示,通过Delete键删除它
-
Top Edges
表示顶边对齐,BottomLayoutGuide
限制了视图能够放置的最低位置,Relation
是指设定的距离之间的关系,Constant
是约束值,Priority
是约束等级,当有相同的约束作用于两个视图之间时,等级高的约束优先 - 使用堆视图
StackView:
两个方向的堆视图还可以任意嵌套,堆视图中子视图的布局是由堆视图管理的,子视图不需要添加约束,但是堆视图本身是要添加约束的 - 资源分辨率--Ul设计人员 :资源图片的大小, 单位是"像素"
- 设计分辨率--开发人员:逻辑上的屏幕大 小 ,单位是“点”
- 屏幕分辨率--一般用户:渲染到屏幕上以展示给用户
-
Any
(任意)是默认情况,但通常情况下很少使用 ,因此Size Class
九宫格可以简化为Size Class
四个象限 - 选择可用的屏幕空 间 ,点击
Vary for Traits
按钮,提示Varying 4 CompactHeight Devices
, 说明这个变化会影响4个高度”紧凑"的设备,即hCompact
-
NSRange
/CGRect
/CGSize
/CGPoint
:本质为struct
Swift语言
- 唯一能够像现存类添加属性(含有实例变量的属性)的方法是类扩展,由于括号内总是为空,所以类扩展又被称为匿名范畴
- 指定初始化方法。这个方法通常应该拥有最多的可能性的初始化方法(例如拥有最多的参数),并且可以方便的被其他初始化方法调用
- 还可以实现一个标准的
init
方法,以提供合适的默认值 - 超类的初始化方法有可能未能成功初始化对象,并返回
nil
,所以读者应该在进行自身的初始化工作之前,总是检查self
是否为nil
- 使用
swift
不能像C语言那样,用0表示false
,用非0表示true
。也不能像OC那样用YES
表示true
,用No
表示false
。只能用true
和fasle
网友评论