创建类的对象返回的值其实是类的第一个属性的地址
但是类的第一个属性是isa指针,对象的地址就是lis的地址,而isa的值就是创建此类对象的类的地址。
其实类也是一个对象,也就意味着person(类名)也是一个对象,平时我们所说的创建一个对象其实就是通过一个类对象创建一个新的类对象。类对象是系统自动帮我们创建的,里面保存了当前对象的所有方法。而实例对象是程序员通过手动(new)来创建的,每一个实例对象中都有一个isa指针指向了创建他的那个类对象(类)
程序在被装载进内存后,将被编译到代码区中,并在内存中创建一个类对象,之后,通过类对象可以实例化一个类的实例对象,实例化完成后将创建好的对象的地址返回给一个对象指针,实例对象在堆区,而指针变量在栈区。在创建好的对象中含有一个isa指针,该指针指向创建此对象的类对象,而指针变量的值其实就是该isa指针的地址。
实例对象调用实例方法时,首先通过地址找到堆对象,再通过对象的isa属性找到类对象的地址,再找到相应的方法执行方法
类方法的化会比实例方法要快,因为少了寻找类的步骤
类中只有声明没有实现不可以,但可以没有声明只有实现
多线程
什么是进程
进程是指系统中正在运行但一个应用程序
每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内
通过活动监视器可以查看mac系统中所开启的进程
线程
什么是线程
1个线程想要执行任务,必须得有线程
一个进程中所有的任务都在线程中执行
线程的串行
一个线程中的所有任务的执行都是串行的,如果要在一个线程中执行多个任务,那么只能按顺序执行这些任务,在同一时间内线程只能执行一个任务
什么是多线程
1个进程中可以开启多个线程,每个线程可以(并行)执行不同的任务
多线程的原理
同一时间内,cpu只能处理一条线程,只有一条线程在工作
多线程并发执行其实是cpu快速在多条线程之间进行切换(调度)
如果cpu调度线程的时间足够快,就造成类多线程并发执行的假象
注意:如果线程非常非常多,cpu会累死,消耗大量cpu内存资源
每条线程被调用执行的频次会降低(线程的只从效率低)
多线程的优缺点
多线程的优点
能适当提高程序的执行效率
能适当提高资源利用率(cpu,内存利用率)
多线程的缺点
多线程是有开销的,ios主要成本包括:内核数据结构,栈空间(子线程512kb,主线程1MB,也可以使用setStacksize设置,但是必须在4kb的倍数,最小是16kb)创建线程大约需要90毫秒的时间
如果开启大量的线程会降低程序的性能
线程越多cpu在调度 线程上的开销就越大
程序设计更加复杂:比如多线程之间的通信,多线程之间的数据共享
多线程在ios中的应用
什么是主线程
一个ios程序运行结束后,会默认开启一条主线程,称为主线程或UI线程
主线程住的主要作用
显示/刷新UI界面
处理UI事件(比如点击事件,滚动事件,拖拽事件等)
主线程的使用注意:
别将比较耗时的操作放到主线程中
耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种卡的环境体验
耗时操作的执行
如果耗时操作放在子线程(后台线程,非主线程)
ios实现方案
pthread和NSTread是面向线程开发的,GCD和NSOperation的化是封装好了的,更加面向对象
多线程的安全隐患
资源共享
一块资源可能被多个线程共享,也就是多个线程可能会访问同一块资源
比如多个线程访问同一个对象,同一个变量,同一个文件
当多个线程同时访问同一块资源时,很容易引发数据错乱和数据安全问题
安全隐患解决----互斥锁
互斥锁使用格式“
@synchronized(锁对象){
//需要锁定的代码
注意:锁定一份代码只用一把锁,用多把锁是无效的
}
互斥锁的优缺点:
优点:能有效防止多线程抢夺资源造成的数据安全问题
缺点:需要消耗大量cpu资源
互斥锁使用的前提:多套线程抢夺同一块资源
相关专业术语:线程同步
线程同步的意思是:多跳线程在同一条线上执行(按顺序地执行任务)
互斥锁就是使用了线程同步技术,多线程默认是线程异步的,即各做各的不互相影响
原子和非原子
atomic是线程安全的,但他需要消耗大量的资源,因为每一次调用属性的set方法时,他都会加一个同步锁以保证线程安全,noatomatic则不存在这个问题,他不加同步锁,因此效率高,但他并不安全。
多线程NSThread
多线程的创建一般由三种方式
http://blog.csdn.net/hbblzjy/article/details/51565590
- (id)initWithTarget:(id)targetselector:(SEL)selectorobject:(id)argument
+ (void)detachNewThreadSelector:(SEL)aSelectortoTarget:(id)aTargetwithObject:(id)anArgument
第一个是实例方法,第二个是类方法
还有一种就是隐式调用
[self performselectorInbackgroud:withObject];
实例方法可以返回一个线程对象的指针,可以对线程对象进行操作,类方法不返回指针,直接开子线程进行操作。在后台开启一个线程执行相应的方法。
一般将比较耗时的操作放在子线程中主线程就负责ui的显示就好
在子线程中下载好了图片等数据后,可以执行返回主线程的操作,将数据作为参数传回给主线程,以供主线程使用
通过简单的交互就可以实现主线程和子线程之间的通信
通过执行performSelector方法可以选择不同的线程,进行相应的通信,但是这里却难以实现多个线程之间的通信,因为这里的线程只是一个局部变量,执行完相应操作后就会被销毁,再调用方法就没有意义了
要解决以上问题需要学习NSRunloop
什么是GCD
全称是Grand Central Dispatch 可翻译为“牛逼的中枢调度器”
GCD的优势
GCD是苹果为多核的并行运算提出的解决方法
GCD会自动利用更多的CPU内核(比如四核,六核)
GCD会自动管理线程的生命周期(线程创建,调度任务,销毁线程)
程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码
参考:http://www.jianshu.com/p/d56064507fb8
oc学习------字符串
c语言中的字符串不是对象,oc中对象是对象,因此具有方法(即行为),c++中的string 和这个有点像
nsstring * str = @"123";
[nsstring stringWithFormat:];//格式话一个字符串,返回一个字符串的地址
c语言中sizeof是返回字符或类型所占的空间,而oc中的是返回个数,不管是中文还是英文字符
程序中,类其实也是一个对象,在程序进入内存时,代码会被编译到代码区中存放,并在堆区中自动创建一个类对象,该类对象保存了类所有的方法。当程序调用new方法在堆上创建一个新的对象时,将先对对象的属性进行初始化,初始化完成后,将返回对象的地址,这个地址是类的实例对象的第一个属性的地址,即isa指针的地址,这个isa指针的值也是一个地址,这个地址的值就是系统自动创建的类对象在堆中的地址。程序中,当程序通过对象的指针访问对象的方法时,首先通过地址找到堆中的实例对象,再听过isa指针找到创建实例对象的类对象,最后通过匹配所调用的方法,以执行所需要的操作。(类对象中应该也是有属性的,要不然这个属性该存在哪里呢,前面说实例对象是通过类对象来创建的,如果类对象都没有属性,那么属性在哪里呢)
oc中结构体作为对象的属性
结构体是中,结构体对象之间的赋值是拷贝,应该是浅拷贝,类如果有一个二结构体属性的话,在对其赋值时可以一个一个的赋值,也可以创建一个整体的结构体对其进行赋值。但是,我记得有些cgrect那些结构体只能通过整体进行赋值。反正就度用整体去替换就好了
#pragra mark - 人
空格加-加空格 加人就行