1、隐藏键盘的方式
- 抛出第一响应者(resignFirstResponse)
- 设置UIView的endEditting = YES
2、UIView的tranform属性的指令特性
3、数组的懒加载:重写getter方法,判断为nil时才初始化
4、UIImageView和UIButton的区别
- UIImageView比UIButton效率更高,因为减少了事件监听处理,节省资源
- UIImageView继承自UIView,而UIButton继承自UIRespond
- 设置按钮的整体内容对齐方式:contentHorizontalAlignment属性
- 设置按钮中整体内容距离按钮左边的左边距:contentEdgeInsets属性
- 设置按钮中title距离左边的距离:titleEdgeInsets
5、UIImage加载时不同方法的缓存管理的区别
- UIImage的imageNamed:方法用来加载少量图片时使用,图片一直存在与内存中
- imageWithContentOfFile:方法在用完后立即释放,节省内存
6、instancetype和id的区别
1》instancetype只能用作方法的返回值,而id是通配符,类似于void
2》instancetype类比id的优点
- 是类型更灵活
- 解决id编译不警告问题
- 表示当前类的指针类型
3》id对象不能使用点语法,id对象能调用任何对象的getter/setter方法
7、路径
1》路径主要用于文件读写时
2》NSBundle:应用程序的安装目录(根目录),内部文件不可更改
3》沙盒:内部可创建或修改文件,其他应用不可访问
- xib文件是开发过程中的文件后缀,编译运行到手机后,经过加密处理转成nib文件
- NSBundle的loadNibName:ower:option返回数组时通过列表中的顺序决定加载到数组内的顺序
8、UIButton
- UIBUtton的image在左,titleLabel在右
- backgroundImage是背景图
- 通过currentTitle可以获得按钮当前状态的title
- 对象方法sizeToFit能自动调整大小,式按钮跟image的尺寸相同
- 让数组中的每个对象都调用一次某个方法,可以通过数组对象的makeObjectsPerformSelector:方法实现
9、设备分辨率
手机型号
|
像素点数
|
分辨率
|
倍数
|
iPhone3GS
|
320*480
|
320*480
|
1X
|
iPhone4/s
|
320*480
|
640*960
|
2X
|
iPhone5/s
|
320*568
|
640*1136
|
2X
|
iPhone6
|
375*667
|
750*1334
|
2X
|
iPhone6+
|
414*736
|
1242*2280
|
3X
|
10、启动界面
1》设置方法:
- Target->General->App Icons and Launch Images->Launch images Source
2》特点:
- 启动界面是一张图片,编译器通过LaunchScreen.xib生成一张启动图片放在沙盒内
- 启动图片的尺寸决定了应用内部控制器view的尺寸
- 通过autoLayout设置LaunchScreen.xib来实现屏幕适配
11、KVC:Key-Value-Coding
1》字典转模型时可以使用,比直接设置模型属性更灵活,因为key可以动态更改,而属性名无法更改
2》setValuesForKeysWithDictionary:的使用条件
- 键和模型属性名字统一
- 属性不能多于字典的键值个数
3》setValue:forKeyPath:比setValue:forKey:更灵活(前者可以传类似@“person.name”的键)
4》字典转模型底层原理
- 遍历字典中所有的key,首先在对象中查找是否responseToSelector:@selector(setKey:),若有,则调用并赋值
- 其次,检查下划线key属性并赋值
- 然后检查key属性并赋值
- 最后报错崩溃
12、UIScrollView
- 两大功能:缩放和滚动
- 子控件的个数多于2,因为有两个默认的子控件(横竖滚动条)
- 监听滚动,可以在- (void)layoutSubviews方法进行监听
13、计时器(暂停时就会被销毁)
1》NSTimer
- 特点:大于1秒时使用,不精确(考虑屏幕刷新频率问题)
- 调用timeWithXXX创建的timer,需要调用一次fire才能启动
- 调用scheduleXXX创建的timer,不需要调用fire,自动启动
- 设置定时器的优先级[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModels]
2》CADisplayLink
- 精确计时器,主要用于做时钟动画(游戏开发中常用)
- 如果定时器调用的频率非常高(<1s)或重绘的时候使用
- 一秒调用60次,恰好是屏幕刷新频率
14、UITableView
1》UITableView实现的功能比for循环更高效,因为内部有缓存机制
2》UITableViewDataSource方法
* 一共有多少组
- (NSInteger)numberOfSectionInTableView:(UITableView *)tableView;
* 每组有多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
* 每行显示什么内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath)indexPath
3》设置UITableView的cell的高度
- 法一:tableView.rowHeight = myHeight
- 法二:通过UITableViewDelegate的代理方法实现
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
4》UITableView的局部刷新方法
- (void)reloadRowAtIndexPaths:withRowAnimation:
5》类比UICollectionView
6》监听UIView的addSubviews事件需要在以下方法中处理
- (void)willMoveToSuperView:(UIView *)newSuperView;
控件添加到父控件可以在- (void)didMoveToSuperView中进行监听
7》footer和header的重用问题以及高度设置(footerHeight、headerHeight)
8》UITableView的headerView创建时的frame都是0,直到tableView要展示的时候才为其frame赋值,解决方法是重写layoutSubviews方法
9》注册机制
- dequeueReusableCellWithIdentifier:方法的底层原理
(1)首先根据唯一标识去缓存池取
(2)若没有获得,则查看storyboard中有没有注册cell,如果有,就直接创建
- 通过dequeueReusableCellWithIdentifier:forIndexPath:方法只能在有注册cell时使用
15、自定义UITableViewCell
1》局部刷新tableView时其总行数不变(使用条件),如果行数变化时刷新界面,需要调用reloadData方法,不能用reloadRowAtIndexPaths方法
2》heightForRowAtIndexPath:要先于cellForRowAtIndexPath:被调用
3》cell的常用属性
- accessoryType(右侧小按钮)
- accessoryView(自定义右侧小按钮)
- backgroundView
- selectedBackgroundView
- imageView
- textLabel
- detailTextLabel
- UITableViewCell默认三个子控件:imageView、textLabel、detailTextLabel,而UICollectionViewCell没有默认子控件,需要自己添加
4》使用静态单元格
- 必须使用UITableViewController,不能使用普通的UIViewController
- 不能在tableViewController中实现任意的数据源方法
- 静态单元格的最大组数是固定死的,不能超过,超过就会报错(崩溃)
- 在iOS7之后,导航控制器下的所有UIScrollView的顶部都会额外添加64高度的滚动区域(tableView.contentInset.top)
5》dequeueReusableXXX:forIndexPath:方法从缓存池获取cell时,必须先在viewDidLoad中注册cell
6》设置cell间的分割线
- 法一:自定义cell,在- (void)awakeFromNib方法中添加cell底部的分割线,该方法从xib加载完成的时候调用,只调用一次;或者使用懒加载方法添加
- 法二:添加tableView.tableFooterView = [[UIView alloc] init];
- 注意:
(1)seperatorInset在iOS8之前可以设置分割线长度
(2)在iOS8之后,由于autoLayout导致此方法无效,需要重写控制器的- (void)viewDidLayoutSubviews方法,在实现时取消约束边缘,即tableView.layoutMargins = UIEdgeInsetsZero,同时取消cell的约束边缘
16、作用域
1》函数的作用域
- extern完整的声明或定义外部函数,默认为外部函数,所以此关键字可以省略
- static声明或定义一个内部函数,只能在本文件被访问,所以若想外部调用,可通过间接调用(定义接口)
2》变量的作用域
<1>全局变量
*外部变量:定义的变量能被本文件和其他文件访问
**默认情况下所有的全局变量都是外部变量
**不同文件中的同名外部变量,都代表同一个变量
**extern只能声明一个外部变量
*内部变量:定义的内部变量只能被本文件访问,不能被其他文件访问(用static修饰)
**不同文件中的同名内部变量互不影响
<2>局部变量:(用static修饰)
*局部变量只能在函数内部使用,函数执行完时被释放
*若用static修饰,则只分配一次内存空间,程序结束的时候才被销毁
*static并不会改变局部变量的作用域
17、通知和代理
1》区别
- 通知是多对多,代理是一对一
- 通知无需强制实现,代理必须实现@required标记的代理方法
2》通知的执行顺序(一对多时):NSNotificationCenter是单例,根据addObserver的先后顺序依次执行方法回调
3》监听移除:当监听对象被销毁时要移除通知的监听,否则可能会出现野指针问题
18、快捷键
- command+option+=用于解决约束警告
- command+option+enter打开拖线界面
- command+enter关闭拖线界面
19、info.plist
- bundle name:安装到手机上的应用名字
- bundle identifier:应用的唯一标识
- bundle version:软件版本号
20、pch文件
- 是一个头文件
- pch中的内容可以被项目中的其他所有源文件共享和访问
- 作用:添加公用的宏、公用的头文件
- __OBJC__用来判断当前文件是否是OC文件
- ...表示宏里的可变参数
- __VA_ARGS__表示函数里面的可变参数
- #define DEBUG表示当前正在调试阶段