@property (nonatomic,readwrite,copy) NSString *name;
属性的特性 可以分为四类:
原子性
(1)atomic 原子性,会保证线程安全,也就是说同一时间内只能有一个线程在访问,有一个加锁的过程,该线程访问结束之后,有一个解锁的过程。本意是保证对象的存取(setter/getter方法是线程安全的,但不能保证这个对象是线程安全的)
(2)nonatomic 非原子性,不保证线程安全,但是效率要比atomic高很多,一般情况下使用没有问题,因为我们在使用setter和getter方法时,有时可能特别频繁,使用atomic会严重影响操作的效率,所以苹果官方推荐对于原子特性建议使用nonatomic.
在默认情况下,由编译器所合成的方法通过锁定机制确保其原子性(atomicity),如果属性具备nonatomic特性,则不需要同步锁。
一般iOS程序中:所有属性都声明为nonatomic.原因是:
在iOS中使用同步锁的开销比较大,这样会影响性能问题。一般情况下并不要求属性必须是“原子”的,因为这并不能保证线程安全,若要实现”线程安全“的操作,还需采用更为深层的锁定机制才可以。
例如:一个线程在连续多次读取这个属性的值的时候有别的线程正在改写该值,那么即便是声明为atomic属性,也还是会读取到不同的值。
所以atomic原子性也并不意味着线程就是安全的,只是增加安全的几率而已,更好的避免线程错误。
读/写权限
readwrite (既可读,又可写)既生成getter方法,也生成setter方法,默认是属性是readwrite
内存管理含义
asign:
只会执行针对”纯量类型“(CGFloat,NSInteger,BOOL等)的简单赋值操作 。
strong
此特性表明该属性定义了一种”拥有关系“,为这种属性设置新值时,设置方法会先保留新值,并释放旧值,然后再把新值赋值上去。
weak
此特质表明该属性定义了一种”非拥有关系“,为这个属性设置新值时,设置方法既不保留新值,也不释放旧值,此特质同assign相似,然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。
举个🌰上图了,当str赋值为空时,str1也变成了空
屏幕快照 2017-08-03 下午5.05.32
unsafe_unretained
此特质和assign相同,但是它适用于”对象类型“,表达一种”非拥有关系“,但是当目标对象遭到摧毁时,属性值不会自动清空,这点和weak有区别。
copy
此特质表明的所属关系和strong类似,然而设置方法并不保留新值,而是将其拷贝
方法名
getter=<name>
setter=<name>
进程和线程的区别?同步异步的区别?并行和并发的区别
进程 是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位.
线程 是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但是它可与同属一个进程的其他的线程共享进程所拥有的全部资源
同步:只在同一个线程里执行任务 就像公交车 只有一个上车的门
异步:可以开辟线程来执行任务 举个🌰 公交车 往往有两个门用来下车,这两个门就相当于多个线程
并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)
区别:并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。倘若在计算机系统中有多个处理机,则这些可以并发执行的程序便可被分配到多个处理机上,实现并行执行,即利用每个处理机来处理一个可并发执行的程序,这样,多个程序便可以同时执行。
数据持久化的几个方案
1.plist 存储字典数组比较好用
2.preference:偏好设置,实质也是plist
3.NSKeyedArchiver:归档,可以存储对象
4.SQLite数据库,经常用第三方FMDB
5.coreData:数据库存储,苹果官方提供
Runtime
1.objc在向一个对象发送消息时,发生了什么?
根据对象的isa指针找到类对象id,在查询类对象里面的methodLists方法函数列表,如果没有在好到,在沿着superClass,寻找父类,再在父类methodLists方法列表里面查询,最终找到SEL,根据id和SEL确认IMP(指针函数),在发送消息;
3.什么时候会报unrecognized selector错误?iOS有哪些机制来避免走到这一步?
当发送消息的时候,我们会根据类里面的methodLists列表去查询我们要动用的SEL,当查询不到的时候,我们会一直沿着父类查询,当最终查询不到的时候我们会报unrecognized selector错误
当系统查询不到方法的时候,会调用+(BOOL)resolveInstanceMethod:(SEL)sel动态解释的方法来给我一次机会来添加,调用不到的方法。或者我们可以再次使用-(id)forwardingTargetForSelector:(SEL)aSelector重定向的方法来告诉系统,该调用什么方法,一来保证不会崩溃。
4.能否向编译后得到的类中增加实例变量?能否向运行时创建的类中添加实例变量?为什么?
1.不能向编译后得到的类增加实例变量
2.能向运行时创建的类中添加实例变量
解释:
1.编译后的类已经注册在runtime中,类结构体中的objc_ivar_list实例变量的链表和instance_size实例变量的内存大小已经确定,runtime会调用class_setvarlayout或class_setWeaklvarLayout来处理strong weak引用.所以不能向存在的类中添加实例变量
2.运行时创建的类是可以添加实例变量,调用class_addIvar函数.但是的在调用objc_allocateClassPair之后,objc_registerClassPair之前,原因同上.
5.runtime如何实现weak变量的自动置nil?
runtime 对注册的类, 会进行布局,对于 weak 对象会放入一个 hash 表中。 用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会 dealloc,假如 weak 指向的对象内存地址是a,那么就会以a为键, 在这个 weak 表中搜索,找到所有以a为键的 weak 对象,从而设置为 nil。
6.给类添加一个属性后,在类结构体里哪些元素会发生变化?
instance_size :实例的内存大小
objc_ivar_list *ivars:属性列表
RunLoop
参考文章:深入理解runloop
1.runloop是来做什么的?runloop和线程有什么关系?主线程默认开启了runloop么?子线程呢?
runloop:字面意思就是跑圈,其实也就是一个循环跑圈,用来处理线程里面的事件和消息。runloop和线程的关系:每个线程如果想继续运行,不被释放,就必须有一个runloop来不停的跑圈,以来处理线程里面的各个事件和消息。主线程默认是开启一个runloop。也就是这个runloop才能保证我们程序正常的运行。子线程是默认没有开始runloop的
2.runloop的mode是用来做什么的?有几种mode?
model:是runloop里面的模式,不同的模式下的runloop处理的事件和消息有一定的差别。系统默认注册了5个Mode:(1)kCFRunLoopDefaultMode: App的默认 Mode,通常主线程是在这个 Mode 下运行的。(2)UITrackingRunLoopMode: 界面跟踪 Mode,用于 ScrollView 追踪触摸滑动,保证界面滑动时不受其他 Mode 影响。(3)UIInitializationRunLoopMode: 在刚启动 App 时第进入的第一个 Mode,启动完成后就不再使用。(4)GSEventReceiveRunLoopMode: 接受系统事件的内部 Mode,通常用不到。(5)kCFRunLoopCommonModes: 这是一个占位的 Mode,没有实际作用。注意iOS 对以上5中model进行了封装NSDefaultRunLoopMode;NSRunLoopCommonModes
3.为什么把NSTimer对象以NSDefaultRunLoopMode(kCFRunLoopDefaultMode)添加到主运行循环以后,滑动scrollview的时候NSTimer却不动了?
nstime对象是在NSDefaultRunLoopMode
下面调用消息的,但是当我们滑动scrollview的时候,NSDefaultRunLoopMode
模式就自动切换到UITrackingRunLoopMode
模式下面,却不可以继续响应nstime发送的消息。所以如果想在滑动scrollview的情况下面还调用nstime的消息,我们可以把nsrunloop的模式更改为NSRunLoopCommonModes
4.苹果是如何实现Autorelease Pool的?
Autorelease Pool作用:缓存池,可以避免我们经常写relase的一种方式。其实就是延迟release,将创建的对象,添加到最近的autoreleasePool中,等到autoreleasePool作用域结束的时候,会将里面所有的对象的引用计数器-1.autorelease
有没有用过运行时,用它都能做什么?(交换方法,创建类,给新创建的类增加方法,改变isa指针)
交换方式:一般写在类的+(void)load方法里面
/** 获取原始setBackgroundColor方法 /
Method originalM = class_getInstanceMethod([self class], @selector(setBackgroundColor:));
/* 获取自定义的pb_setBackgroundColor方法 /
Method exchangeM = class_getInstanceMethod([self class], @selector(pb_setBackgroundColor:));
/* 交换方法 */
method_exchangeImplementations(originalM, exchangeM);
创建类:
Class MyClass = objc_allocateClassPair([NSObject class], "Person", 0);
添加方法
/**参数一、类名参数
二、SEL 添加的方法名字参数
三、IMP指针 (IMP就是Implementation的缩写,它是指向一个方法实现的指针,每一个方法都有一个对应的IMP)
参数四、其中types参数为"i@:@“,按顺序分别表示:具体类型可参照官方文档i 返回值类型int,若是v则表示void@ 参数id(self): SEL(_cmd)@ id(str)
V@:表示返回值是void 带有SEL参数 (An object (whether statically typed or typed id))
*/
class_addMethod(Person, @selector(addMethodForMyClass:), (IMP)addMethodForMyClass, "V@:");
添加实例变量
/**参数一、类名参数
二、属性名称参数
三、开辟字节长度参数
四、对其方式参数
五、参数类型 “@” 官方解释 An object (whether statically typed or typed id) (对象 静态类型或者id类型) 具体类型可参照官方文档return: BOOL 是否添加成功
*/
BOOL isSuccess = class_addIvar(Person, "name", sizeof(NSString *), 0, "@");
isSuccess?NSLog(@"添加变量成功"):NSLog(@"添加变量失败");
SDWebImage的缓存策略?
sd加载一张图片的时候,会先在内存里面查找是否有这张图片,如果没有会根据图片的md5(url)后的名称去沙盒里面去寻找,是否有这张图片,如果没有会开辟线程去下载,下载完毕后加载到imageview上面,并md(url)为名称缓存到沙盒里面。
AFN为什么添加一条常驻线程?
AFN 目的:就是开辟线程请求网络数据。如果没有常住线程的话,就会每次请求网络就去开辟线程,完成之后销毁开辟线程,这样就造成资源的浪费,开辟一条常住线程,就可以避免这种浪费,我们可以在每次的网络请求都添加到这条线程。
KVO的使用?实现原理?(为什么要创建子类来实现)
kvo:键值观察,根据键对应的值的变化,来调用方法。注册观察者:addObserver:forKeyPath:options:context:实现观察者:observeValueForKeyPath:ofObject:change:context:移除观察者:removeObserver:forKeyPath:(对象销毁,必须移除观察者)注意使用kvo监听A对象的时候,监听的本质不是这个A对象,而是系统创建的一个中间对象NSKVONotifying_A
并继承A对象,并且A对象的isa指针指向的也不是A的类,而是这个NSKVONotifying_A
对象kvo详解kvo详解2
.KVC的使用?实现原理?(KVC拿到key以后,是如何赋值的?知不知道集合操作符,能不能访问私有属性,能不能直接访问_ivar)
kvc:键值赋值,使用最多的即使字典转模型。利用runtime获取对象的所有成员变量, 在根据kvc键值赋值,进行字典转模型setValue: forKey: 只查找本类里面的属性setValue: forKeyPath:会查找本类里面属性,没有会继续查找父类里面属性。kvc详解
通知,代理,KVO的区别?
应用程序的生命周期
第一次或者已关闭程序 启动或者再次启动这个应用的动态跃迁状态变化是:
后台运行或者挂起的状态变化
应用退出的场景
(包含:applicationWillResignActive:)
挂起状态的重新运行
参考博客:
应用程序的生命周期
项目
1.有已经上线的项目么?
2.项目里哪个部分是你完成的?(找一个亮点问一下如何实现的)
3.开发过程中遇到过什么困难,是如何解决的?
学习
4.遇到一个问题完全不能理解的时候,是如何帮助自己理解的?举个例子?
5.有看书的习惯么?最近看的一本是什么书?有什么心得?
6.有没有使用一些笔记软件?会在多平台同步以及多渠道采集么?(如果没有,问一下是如何复习知识的)
7.有没有使用清单类,日历类的软件?(如果没有,问一下是如何安排,计划任务的)
TeamBition,redmine
8.平常看博客么?有没有自己写过?(如果写,有哪些收获?如果没有写,问一下不写的原因)