cocoapods 命令
-
pod init
:初始化; -
pod install
:安装第三方库; -
pod update
:更新第三方库; -
pod search <第三方库名称>
:查找第三方库;
git 常用命令
本地操作:
-
git init
:初始化本地库; -
git status
:查看工作区、暂存区的状态; -
git add <file name>
:将工作区的“新建或修改”添加到暂存区;(不带文件名的话,就是对仓库中的所有文件进行操作) -
git rm --cached <file name>
:移除暂存区中的内容; -
git commit <file name>
:将暂存区的内容提交到本地; -
git commit -m "提交日志" <file name>
:将暂存区的内容提交到本地。
日志:
-
git log
:查看历史提交;
版本控制:
-
git reset --hard HEAD
:强制工作区、暂存区、本地库为当前HEAD指针所在的版本; -
git reset --hard HEAD^
:回退一个版本; -
git reset --hard HEAD~1
:回退 n 个版本,~
后面的数字表示回退几个版本;
比较差异:
-
git diff
:比较工作区和暂存区的所有文件差异; -
git diff <file name>
:比较工作区和暂存区的指定文件的差异;
分支操作:
-
git branch
:查看当前分支; -
git branch -v
:查看所有分支; -
git branch -d <分支名>
:删除指定的本地分支; -
git branch <分支名>
:新建分支; -
git checkout <分支名>
:从当前分支切换到指定分支; -
git merge <被合并分支名>
:将指定的分支合并到当前分支; -
git checkout -b <本地分支名> origin/<远程分支名>
拉取远程分支到本地。
本地仓库与远程仓库交互:
-
git clone <远程仓库地址>
:克隆远程仓库到本地,为本地库新建orgin
别名,并初始化本地库; -
git remote -v
:查看远程仓库地址别名; -
git remote add <别名> <远程仓库地址>
:为远程仓库地址新创建一个别名; -
git remote rm <别名>
:删除本地中远程库别名; -
git push <别名> <分支名>
:将本地库某个分支推送到远程库,分支必须指定; -
git pull <别名> <分支名>
:把远程库的修改拉取到本地;
什么是面向对象编程?
面向对象编程把面向对象的思想应用于软件开发。对象是由数据和所允许的操作组成的封装体,与客观实体有直接对应关系,类定义了具有相似性质的一组对象。继承性是对具有层次关系的类的属性和操作进行共享的一种方式。所谓面向对象就是基于对象概念,以对象为中心,以类和继承为构造机制,来认识、理解、 刻画客观世界,并设计、构建相应的软件系统。面向对象编程有以下三大特征:
- 封装,把客观事物封装成抽象的类,并且类可以将自己的数据和方法只对可信的类或对象公开,对不可信的类或者对象隐藏。
- 继承,子类继承父类,子类可以使用父类的所有功能,并在无需改动父类的情况下对这些功能进行扩展。
- 多态,继承自同一个父类的不同子类对象以它们自己的方式响应相同的消息。
为什么说Objective-C是一种动态编程语言?
动态编程指的是程序在运行时可以改变其结构,新的函数可以被引进,已有的函数可以被删除。而Objective-C具有在运行时动态确定对象的类型,动态绑定方法的实现和动态加载资源(在运行时构建新的类,给类添加属性和方法)这几种特性。因此,Objective-C是一种动态编程语言。
atomic和non-atomic修饰的属性有什么区别?
- atomic:原子性,atomic修饰的属性是线程安全的(只是保证了属性的setter和getter的线程安全),但是效率低。
- non-atomic:非原子性,non-atomic修饰的属性是线程不安全的,但效率高。
如何使用atomic才能保证线程安全?
atomic
修饰的属性,只是保证了setter
和getter
的线程安全,并不是所有操作都是线程安全的。例如,当在不同的线程对一个原子性的可变数组分别进行插入和删除数据的操作时,就会出现问题。可以使用锁来保证线程安全。有以下几种加锁方式:
-
@synchronized
指令,使用最简单,性能也最差。 - 信号量。
- 互斥锁。
- 递归锁。
-
OSSpinLock
自旋锁(有线程优先级反转bug。如果访问自旋锁的线程的优先级都是相同的,则没有问题)。
@synthesize和@dynamic分别有什么作用?
@synthesize
告知编译器自动为给定属性生成set和get方法。
@dynamic
告知编译器不要自动生成给定属性的set和get方法,这两个方法会由开发者手动生成。
readwrite,readonly,assign,retain,strong,copy,weak属性关键字的作用。
-
readwrite
:属性可读可写,也就是说外部可以访问该属性并且可以修改该属性的值。 -
readonly
:属性只读,也就是说外部只能访问该属性,但不能修改该属性的值。 -
assign
:给属性分配值时,不会增加属性值的引用计数。 -
retain
:给属性分配值时,会使属性值的引用计数加1。 -
weak
:ARC模式下,给属性分配值时,不会增加属性值的引用计数。 -
strong
:ARC模式下,给属性分配值时,会使属性值的引用计数加1。 -
copy
:内容拷贝,分为浅拷贝和深拷贝。- 浅拷贝:只是拷贝了指向对象的内存地址的指针,对象的引用计数会加1。
- 深拷贝:会拷贝对象的具体内容,拷贝得到的对象和原对象的内容是相同的,但是内存地址是不同的。
#import、#include 和 @class 的区别
import
是Objective-C导入头文件的关键字,include
是C/C++导入头文件的关键字。使用include
导入头文件时,相当于拷贝导入的头文件中的声明内容。如果使用include
重复导入某个头文件的话,编译器会报重复定义的错误。而使用import
导入头文件,编译器会在编译时做一次判断,如果已经导入了该头文件就不会再二次导入了。如果不是C/C++文件,应尽量使用import
。并且如果能在.m
文件中import
,就不要在.h
文件中import
。
@class
用于声明某个类,其告诉编译器它后面的内容是一个类的名称,而这个类的具体实现暂时是不知道的。而在一个类的头文件中使用import
导入某个类的时候,这个类的所有信息都会被导入。如果在许多个类的头文件中都使用import
导入了该类,会降低编译器编译的效率。另外,当两个类使用import
互相引用时,编译器会报错,而使用@class
能够避免出现错误。
delegate,block 和 notification 的区别
- delegate:对于同一个协议,一个对象只能设置一个代理,也就是说只能一对一地通信。代理注重信息传输的过程。例如,发起一个网络请求后,我们想要知道此时请求是否已经开始、是否收到了数据、数据是否已经接受完成、数据接收失败,此时就应该在同一个协议中声明对应的委托方法,然后使用一个代理对象调用对应的委托方法来传输这些信息。
- block:block也只能一对一地通信,其注重信息传输的结果。例如,对于某个操作,我们只想知道其操作结果,这时应该使用block。相对于代理,其写法简单,不需要声明协议和委托方法。但使用block时,容易导致循环引用。
- notification:能够一对多地通信。当多个对象都需要对某个操作做出响应时,应该使用通知。
如何实现下拉刷新?
创建一个UIScrollView
的分类,在分类中动态添加一个header属性,header是一个自定义视图,用于显示与刷新状态有关的文字,图片和活动指示器,将其添加到UIScrollView
的头部。为UIScrollView
的contentOffset
属性注册观察者,在contentOffset
更改时,根据当前contentOffset
来判断此时UIScrollView
处于准备刷新、正在刷新中和刷新完毕这三个状态中的哪一种,并根据状态来设置header当前需要显示的内容。
如何使用UICollectionView实现无限循环轮播图?
根据需要展示的图片资源构造一个图片数组,该图片数组包含所有需要展示的图片,同时,把最后展示的图片拷贝一份插入到图片数组的最前面,把最先展示的图片拷贝一份插入到图片数组的最后面,然后将该数组设置为UICollectionView
的数据源。在UICollectionView
滑动到展示图片数组中的最后一张图片的位置时,将UICollectionView
的contentOffset
隐式地切换到展时图片数组中的第二张图片的位置。在UICollectionView
滑动到展示图片数组中的第一张图片的位置时,将UICollectionView
的contentOffset
隐式地切换到展时图片数组中的倒数第二张图片的位置。这样就实现了无限循环展示图片的效果。