IOS随机随学

时间:2023-03-09 17:55:20
IOS随机随学

1.Objective-C是一种面向对象的语言。

2.Objective-C类声明和实现包括两个部分:接口部分和实现部分。

3.Objective-C中方法不是在“.”运算符,而是采用“[]”运算符。有时候方法调用也称为:消息发送。

4.Objective-C中的协议类似于Java中的接口与C++的纯虚类,只有接口部分定义没有实现部分,即只有h文件没有m文件。

5.Objective-C数据类型可以分为:基本数据类型、对象类型和id类型。

(I)基本数据类型有:int、float、double和char类型

(II)对象类型就是类或协议所声明的指针类型,例如:

NSAutoreleasePool* pool,其中NSAutoreleasePool是一个类,NSAutoreleasePool*是它指针类型。

(III)id类型可以表示任何类型,一般只是表示对象类型,不表示基本数据类型。

6. %i 表示十进制的整数,%o表示8进制整数,%#x表示十六进制整数。

7.%f表示浮点数,%e表示科学计数法,%g表示浮点数。

8.Objective—C中声明常量使用关键字const:

9.Objective-C中变量可以分为成员变量、局部变量和局部变量。

10.Objective-C的类声明和实现包括两个部分:接口部分和实现部分。

@interface Song:NSObject{

}

@end

@implementation Song

@end

11.声明property的语法为:@property(参数)类型 名字;

这里的“擦数”主要分为3大类:

(I)读写属性(readwrite/readonly);

(II)内存管理(assign/retain/copy),

(III)原子性atomicity(nonatomic),是关系线程线程安全的,atomicity是原子性的线程安全的,但是会影响性能。如果确定不考虑线程安全问题可以使用nonatomic

12.@public、@private和@protected作用域限定只能修饰的实例成员变量,不能修饰类变量,更不能修饰方法。

13.子类不能继承父类中作用域限定符为@private的成员变量。子类可以重写父类的方法,及命名与父类同名的成员变量。

14.id是泛类型(generic data type),可以用来存放各种类型对象,使用id也就是使用“动态类型”。

15.分类(Category)允许向一个类文件中添加新的方法声明,它不需要使用子类机制,并且在类实现的文件中的同一个名字下定义这些方法。其语法示例实现:

#import "ClassName.h"

@interface ClassName(CategoryName)

//方法声明

@end

分类本质上是通过Objective-C的动态绑定而实现的,通过分类使用能够达到比继承更好的效果。

16.协议(Protocol)与Java的Interface(接口)或者C++的纯虚类形同,就是用来声明接口的。协议只是定义了方法的列表,协议不负责实现方法,目的是让别的类来实现。

协议只有接口部分,没有实现部分,所以没有m文件,关键字@protocol,协议可以继承别的协议,协议中不能定义成员变量。

协议的实现是在类声明的父类之后,加上<>,与类的当个继承不同,协议可以实现多个,表示要实现这个协议,如果有多个协议要实现“,”号分隔:<P1,P2>

17.Objective-C为每个对象提供一个内部计数器,这个计数器跟踪对象的引用次数。所有类都继承自NSObject的对象retain和release方法。

19.内存释放池(Autorelease pool)提供了一个对象容器,每次对象发送autorelease消息时,对象的引用计数并不真正变化,而是向内存释放池中添加一条记录,记下对象的这种要求,直到当内存释放池发送drain或release消息时,当池被销毁前通知池中的所有对象,全部发送release消息真正将引用计数减少,

20.在OC中,-号表示是实例方法,得有对象来调用的,+号表示类方法,可以用类名直接调用。

21.类的定义使用@interface关键字,而实现用@implementation关键字。

22.Objective-C的内存管理基于引用计数。如果要使用一个对象,并希望确保在使用期间对象不被释放,需要保证在使用过程中引用计算>0,在使用过后,把引用计数-1。当引用计数==0时,就会调用销毁方法了、

(I)+1操作

alloc     创建对象时调用alloc,为对象分配内存,对象引用计数加一。

copy     拷贝一个对象,返回新对象,引用计数加一。

retain    引用计数加一,获得对象的所有权

(II)-1操作

release  引用计数减一,释放所有权。如果引用计数减到零,对象会被释放。

autorelease  在未来某个时机释放。

23.内存管理,我们需要遵循一些基本原则:

(1)保证只带有alloc,copy,retain的函数才会让引用计数+1。

(II)在对象的dealloc函数中释放对象,完全依赖引用计数来完成对象的释放。

(III)永远不要直接调用dealloc来释放对象,完全依赖引用计数器来完成对象的释放。

(IV)有很多类方法可以直接出创建autorelease对象

(V)在把一个参数传递出去的时候,因为要交由别人来释放,一般都设置成autorelease对象。

24.进行:程序实体,独立单位,线程容器,老板。

线程:不拥有资源,指令集,打工仔。

25.GCD函数前缀:dispatch_

获取主队列:dispatch_get_main_queue

获取全局队列:dispatch_get_global_queue

自定义队列:dispatch_queue_create

26.图片展示:

  let img=UIImage(named:"IMG_0022");
let imgView=UIImageView(image:img);
self.view.addSubview(imgView);

27.打开网络风火轮

  UIApplication.sharedApplication().networkActivityIndicatorVisible=true;

28. 读取iOS应用的配置信息

        let mainBundle=NSBundle.mainBundle();
let identifier=mainBundle.bundleIdentifier;
let info=mainBundle.infoDictionary;
let bundleId=mainBundle.objectForInfoDictionaryKey("CFBundleName");
let version=mainBundle.objectForInfoDictionaryKey("CFBundleShortVersionString");
print("[identifier]:\(identifier)\n")
print("[bundleId]:\(bundleId)\n");
print("[version]:\(version)\n");
print("[info]:\(info)\n");

29.画两个矩形

        let rect1=CGRectMake(, , , );
let view1=UIView(frame:rect1);
view1.backgroundColor=UIColor.brownColor(); let rect2=CGRectMake(, , , );
let view2=UIView(frame:rect2);
view2.backgroundColor=UIColor.greenColor(); self.view.addSubview(view1);
self.view.addSubview(view2);

30. 按钮

      override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let rect1=CGRectMake(, , , );
let view1=UIView(frame:rect1);
view1.backgroundColor=UIColor.blueColor(); self.view.addSubview(view1); let btAdd=UIButton(frame:CGRectMake(, , , ));
btAdd.backgroundColor=UIColor.grayColor();
btAdd.setTitle("Add",forState:UIControlState.Normal);
btAdd.addTarget(self, action: "addView:", forControlEvents: UIControlEvents.TouchUpInside); self.view.addSubview(btAdd); let btBack=UIButton(frame:CGRectMake(, , , ));
btBack.backgroundColor=UIColor.greenColor();
btBack.setTitle("Switch",forState:UIControlState.Normal);
btBack.addTarget(self, action: "bringViewBack:", forControlEvents: UIControlEvents.TouchUpInside); self.view.addSubview(btBack); let btAdd1=UIButton(frame:CGRectMake(, , , ));
btAdd1.backgroundColor=UIColor.yellowColor();
btAdd1.setTitle("Remove",forState:UIControlState.Normal);
btAdd1.addTarget(self, action: "removeView:", forControlEvents: UIControlEvents.TouchUpInside); self.view.addSubview(btAdd1); }
func addView(sender:UIButton!)
{
let rect=CGRectMake(, , , ); let view3=UIView(frame:rect);
view3.backgroundColor=UIColor.redColor();
view3.tag=;
self.view.addSubview(view3);
}
func bringViewBack(sender:UIButton!)
{
let view=self.view.viewWithTag();
self.view.sendSubviewToBack(view!);
}
func removeView(sender:UIButton!)
{
let view=self.view.viewWithTag();
view?.removeFromSuperview();
}

31.给图像视图添加边框效果、圆角效果、阴影效果

        let image=UIImage(named:"");

        let imageView=UIImageView(image:image);

        imageView.frame=CGRectMake(, , , );

        imageView.layer.shadowColor=UIColor.blackColor().CGColor;
imageView.layer.shadowOffset=CGSizeMake(10.0, 10.0);
imageView.layer.shadowOpacity=0.45;
imageView.layer.shadowRadius=5.0; imageView.layer.cornerRadius=5.0;
imageView.layer.masksToBounds=true; imageView.layer.borderWidth=;
imageView.layer.borderColor=UIColor.lightGrayColor().CGColor; self.view.addSubview(imageView);

32.UIView视图的渐变效果

        let rect=CGRectMake(, , ,);
let gradientView=UIView(frame:rect);
let gradientLayer=CAGradientLayer();
gradientLayer.frame=gradientView.frame
let fromColor=UIColor.yellowColor().CGColor;
let midColor=UIColor.redColor().CGColor;
let toColor=UIColor.purpleColor().CGColor; gradientLayer.colors=[fromColor,midColor,toColor];
view.layer.addSublayer(gradientLayer);
self.view.addSubview(gradientView);

33.UIView视图的纹理填充

        let image=UIImage(named: "");
let patternColor=UIColor.init(patternImage:image!);
self.view.backgroundColor=patternColor;

34.CGAffineTransform放射变换的使用

        let rect=CGRectMake(, , , );
let view=UIView(frame:rect);
view.backgroundColor=UIColor.brownColor();
self.view.addSubview(view); var transform=view.transform;
transform=CGAffineTransformRotate(transform, 3.14/);
view.transform=transform;

35.UITapGestureRecognizer手势之单击、长按、双击

        override func viewDidLoad() {
super.viewDidLoad()
let rect=CGRectMake(, , , ); let imageView=UIImageView(frame: rect); let image=UIImage(named: "");
imageView.image=image; imageView.userInteractionEnabled=true;
self.view.addSubview(imageView); let guesture=UITapGestureRecognizer(target:self,action:"singleTap"); let guesture1=UILongPressGestureRecognizer(target:self,action:"longPress:") let guesture2=UITapGestureRecognizer(target:self,action:"doubleTap");
guesture2.numberOfTapsRequired=;
guesture2.numberOfTouchesRequired=; imageView.addGestureRecognizer(guesture); imageView.addGestureRecognizer(guesture1); imageView.addGestureRecognizer(guesture2); } func singleTap()
{
let alertView=UIAlertController(title:"Infomation",message: "Single Tap",
preferredStyle: UIAlertControllerStyle.Alert)
let OKAction=UIAlertAction(title:"OK",style: .Default){(action)in}
alertView.addAction(OKAction);
self.presentViewController(alertView,animated:true,completion:nil);
} func longPress(gesture:UILongPressGestureRecognizer)
{
if(gesture.state==UIGestureRecognizerState.Began)
{
let alertView=UIAlertController(title:"Information",message:"Long Press",
preferredStyle:UIAlertControllerStyle.Alert );
let OKAction=UIAlertAction(title:"OK",style: .Default){(action)in} alertView.addAction(OKAction)
self.presentViewController(alertView, animated: true, completion: nil);
}
} func doubleTap()
{
let alertView=UIAlertController(title:"Information",message: "Double Tap",
preferredStyle: UIAlertControllerStyle.Alert);
let OKAction=UIAlertAction(title:"OK",style:.Default){(action)in}
alertView.addAction(OKAction);
self.presentViewController(alertView, animated: true, completion: nil);
}

36打电话

(1)使用UIApplication 的openUrl方法实现


37.多线程

(1)ios多线程特殊的规则:必须在主线程更新UI

(2)IOS有三种多线程编程的技术,分别是:

(a)NSThread

(b)NSOperation

(c)GCD(Grand Central Dispatch)

(d)这三种编程方式从上到下,抽象度层次是从低到高的,抽象度越高的使用越简单,也是Apple最推荐使用的。

(3)多线程的好处:

(a)多个线程可以提高应用程序的感知响应。

(b)多个线程可以提高应用程序在多核系统上的实时性能。

(4)GCD

(a)GCD的工作原理:把任务放到对应队列中,根据可用的处理资源,安排这些任务在任何可用的处理器核心上执行。

(b)一个任务可以是一个函数或者是一个block。

(c)GCD中队列称为dispatch queue,它可以保证先进来的任务先得到执行。

(d)dispatch queue分类

(I)main dispatch queue(系统提供的)

(i)全局性的serial queue,所有和UI操作相关的任何都放到这个queue里面,在主线程中执行。

(ii)宏dispatch_get_main_queue()

(II)global dispatch queue(系统提供的)

(i)可以随机地执行多个任务,但是执行完成的顺序是随机的。一般后台执行的任务放到这个queue里面。

(ii)函数dispatch_get_global_queue(0,0);

(III)自定义的dispatch queue

(i)和main dispatch queue类似,同时只执行一个任务,区别在于自定义queue里面放的任何一般和UI操作无关。serial queue通常用于同步访问特定的资源或数据,比如多个线程对同一个文件的写入。

(ii)dispatch_queue_create("SerialQueue",DISPATCH_QUEUE_SERIAL);

(5)提交任务到dispatch queue

(a)同步提交

void dispatch_sync(dispatch_queue_t queue,dispatch_block_t block);

(b)异步提交

void dispatch_async(dispatch_queue_t queue,dispatch_block_t block);

(6)GCD的应用场合

(a)主要应用在本地的多线程处理上,比如解析从网络传输过来的数据。

(b)对于网络方面的多线程控制,更多使用NSOperation,因为NSOperation的控制粒度更加精细。

38.进程

(1)每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内。

(2)1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程)

(3)线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行

(4)线程的串行

(a)1个线程中任务的执行是串行的

(b)如果要在1个线程中执行多个任务,那么只能一个一个地顺序执行这些任务。也就是说,在同一时间内,1个线程只能执行1个任务。

(5)什么事多线程

(a)1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务。

(6)多线程的原理

(a)同一时间,CPU只能处理1条线程,只有1条线程在工作(执行)

(b)多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换)。

(c)如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象。

(d)如果线程非常非常多,(i)CPU会在N多线程之间调度,CPU会累死,消耗大量的CPU资源。(ii)每条线程被调度执行的频次会降低(线程的执行效率降低)

(7)多线程的优点:

(a)能适当提高程序的执行效率

(b)能适当提高资源利用率(CPU、内存利用率)

(8)多线程的缺点

(a)开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能。

(b)线程越多,CPU在调度线程上的开销就越大。

(c)程序设计更加复杂:比如线程之间的通信、多线程的数据共享

(9)主线程

(a)一个IOS程序运行后,默认会开启1条线程,称为“主线程”或“UI线程”

(b)主线程的主要作用

(i)显示、刷新UI界面

(ii)处理UI事件(比如点击事件、滚动事件、拖拽事件等)

(c)主线程的使用注意:别将比较耗时时的操作放在主线程中

(d)耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种“卡”的坏体验

(e)解决方案:将耗时操作放在子线程(后台线程、非主线程)

(10)IOS中多线程的实现方案

(a)PThread:<C语言>

(i)一套通用的多线程API

(ii)适用于Unix\Linux\Windows等系统

(iii)跨平台、可移植

(iv)使用难度大

(v)简单案例

void *run(void *data){
NSThread *current=[NSThread currentThread];
NSLog(@"Click----%@",current);
for (int i=; i<; i++) {
//3.输出线程
NSLog(@"%@",current);
}
return NULL;
}
- (IBAction)btnClick {
//1。获得当前的线程
NSThread *current=[NSThread currentThread];
NSLog(@"btnClick----%@",current); //2.执行一些耗时操作:创建一条子线程
pthread_t threadId;
pthread_create(&threadId, NULL, run, NULL);
}

(b)NSThread:(OC)

(i)使用更加面向对象

(ii)简单易用,可直接操作线程对象

(c)GCD:(C)

(i)旨在替代NSThread等线程技术

(ii)充分利用设备的多核

(d)NSOperation:(oc)

(i)基于GCD(底层是GCD)

(ii)比GCD多了一些更简单使用的功能

(iii)使用更加面向对象

(11)NSThread线程

(a)一个NSThread对象就代表一条线程

(b)创建、启动线程

NSThread*thread=[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];

[thread start];

线程一启动,就会在线程thread中执行self的run方法

(c)主线程相关用法

+(NSThread*)mainThread;//获得主线程

-(BOOL)isMainThread;//是否为主线程

+(BOOL) isMainThread;//是否为主线程

(d)获得当前线程

NSThread *current=[NSThread currentThread];

(e)线程的调度优先级

+(double) threadPriority;

+(BOOL)setThreadPriority:(double)p;

-(double) threadPriority;

-(BOOL)setThreadPriority:(double)p;

调度优先级的取值范围是0.0~1.0,默认0.5,值越大,优先级越高

(f)线程的名字

-(void)setName:(NSString*)n;

-(NSString*)name;

(g)创建线程后自动启动线程

[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

(h)隐式创建并自动启动线程

[self performSelectorInBackground:@selector(run)withObject:nil];

(12)控制线程状态

(a)启动线程

-(void)start;

//进入就绪状态->运行状态。当线程任务执行完毕,自动进入死亡状态

(b)阻塞(暂停)线程

+(void) sleepUntilDate:(NSDate*) date;

+(void)sleepForTimeInterval:(NSTimeInterval)ti;

//进入阻塞状态

(c)强制停止线程

+(void)exit;

//进入死亡状态

//注意:一旦线程停止(死亡)了,就不能再次开启线程

(d)示例

-(void) test
{ NSLog(@"test- 开始-%@",[NSThread currentThread].name);
//[NSThread sleepForTimeInterval:5];阻塞状态 // NSDate *date=[NSDate dateWithTimeIntervalSinceNow:5.0];
// [NSThread sleepUntilDate:date]; for (int i=; i<; i++) { NSLog(@"test- %d-%@",i,[NSThread currentThread].name); if(i==){
[NSThread exit];//线程退出,等同于return; }
} NSLog(@"test- 结束--%@",[NSThread currentThread].name);
}

(13)多线程的安全隐患

(a)1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源。

(b)比如多个线程访问同一个对象、同一个变量、同一个文件

(c)当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题

(14)安全隐患解决---互斥锁

(a)互斥锁使用格式

@synchronized(锁对象){//需要锁定的代码}

//注意:锁定1份代码只能用1把锁,用多把锁是无效的

(b)互斥锁的优缺点

(I)优点:能有效防止因多线程抢夺资源造成的数据安全问题

(II)缺点:需要消耗大量的CPU资源

(c)互斥锁的使用前提:多条线程抢夺同一块资源

(d)线程同步的意思是:多条线程按顺序地执行任务。

(e)互斥锁,就是使用了线程同步技术

(15)原子和非原子属性

(a)OC在定义属性时有nonatomic和atomic两种选择

(b)atomic:原子属性,为setter方法加锁(默认就是atomic)

(c)nonatomic:非原子属性,不会为setter方法加锁

(d)atomic加锁原理

@property (assign,atomic) int age;

-(void) setAge:(int)age

{

  @synchronized(self){

    _age=age;  

  }

}

(e)原子和非原子属性的选择

nonatomic和atomic对比

atomic:线程安全,需要消耗大量的资源

nonatomic:非线程安全,适合内存小的移动设备

(16)线程间通信

(a)什么叫做线程间通信:在1个进程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信。

(b)进程间通信的体现

(I)1个线程传递数据给另1个线程

(II)在1个线程中执行完特定任务后,转到另1个线程继续执行任务。

(c)线程间通信常用方法

-(void)performSelectorOnMainThread:(SEL)aSelector WithObject:(id)arg waitUntilDone:(BOOL)wait;

-(void)performSelector:(SEL)aSelector onThread:(NSThread*)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

(d)示例

-(void)touchesBegan:(NSSet*)touches withEvent:( UIEvent *)event
{
[self performSelectorInBackground:@selector(download)withObject:nil];
}
-(void) download
{
//1.下载图片
NSLog(@"--------begin");
NSURL *url=[NSURL URLWithString:@"http://pic32.nipic.com/20130829/12906030_124355855000_2.png"];
NSLog(@"--------begin");
NSData *data=[NSData dataWithContentsOfURL:url];//耗时
NSLog(@"--------end");
UIImage *image=[UIImage imageWithData:data]; //回到主线程显示图片
// [self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO]; // [self.imageView performSelectorOnMainThread:@selector(setImage:)withObject:image waitUntilDone:NO];
[self.imageView performSelector:@selector(setImage:)onThread:[NSThread mainThread]withObject:image waitUntilDone:NO]; }
-(void)settingImage:(UIImage *)image
{ //2.显示图片```
self.imageView.image=image;
}

(17)GCD

(a)GCD的优势

(I)GCD是苹果公司为多核的并行运算提出的解决方案

(II)GCD会自动利用更多的CPU内核(比如双核、四核)

(III)GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)

(IV)程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

(b)GCD中有2个核心概念

(I)任务:执行什么操作

(II)队列:用来存放任务

(c)GCD的使用就2个步骤

(I)定制任务

(II)确定想要做的事情

(d)将任务添加到队列中

(I)GCD会自动将队列中的任务取出,放到对应的线程中执行

(II)任务的取出遵循队列的FIFO原则:先进先出,后进后出

(f)GCD中有2个用来执行任务的函数

(I)用同步的方式执行任务

dispatch_sync(dispatch_queue_t queue,dispatch_block_t block);

queue:队列

block:任务

(II)用异步的方式执行任务

dispatch_async(dispatch_queue_t queue,dispatch_block_t block);

(III)同步和异步的区别

(i)同步:在当前线程中执行

(ii)异步:在另一条线程中执行

(18)队列的类型

(a)GCD的队列可以分为2大类型

(I)并发队列(Concurrent Dispatch Queue)

(i)可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)

(ii)并发功能只能在异步(dispatch_async)函数下才有效

(b)串型队列(serial Dispatch Queue)

(i) 让任务一个接着一个地执行(一个任务执行完毕后,在执行下一个任务)

(b)比较:同步、异步、并发、串行

同步和异步决定了要不要开启新的线程

(I)同步:在当前线程总执行任务,不具备开启新线程的能力。

(II) 异步:在新的线程中执行任务,具备开启新线程的能力。

并发和串行决定了任务的执行方式

(I)并发:多个任务并发(同时)执行。

(II)串行:一个任务执行完毕后,再执行下一个任务。

(19)并发队列

(a)GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建。

(b)使用dispatch_get_global_queue函数获得全局的并发队列

dispatch_queue_t dispatch_get_global_queue(

  dispatch_queue_priority_t priority,//队列的优先级

  unsigned long flags);//此参数暂时无用,即0即可

dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);//获得全局并发队列

(c)全局并发队列的优先级

(I)#define DISPATCH_QUEUE_PRIORITY_HIGH 2//高

(II)#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0  //默认  中

(III)#define DISPATCH_QUEUE_PRIORITY_LOW(-2) //低

(IV)#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN  //后台

(20)串行队列

(a)GCD中获取串行有2钟途径

(I)使用dispatch_queue_create函数创建串行队列

dispatch_queue_t  queue=dispatch_queue_create(const char *label,//队列名称

dispatch_queue_attr_t attr);//队列属性,一般用NULL即可

dispatch_queue_queue=dispatch_queue_create("cn.itcast.queue",NULL);//创建

dispatch_release(queue);//非ARC需要释放手动创建的队列

(b)使用主队列(跟主线程相关的队列)

(I)主队列是GCD自带的一种特殊的串行队列

(II)放在主队列中的任务,都会放在主线中执行

(III)使用dispatch_get_main_queue()获得主队列

(IV)使用dispatch_get_main_queue()获得主队列

dispatch_queue_t queue=dispatch_get_main_queue();

(21)各种队列的执行效果

            全局并发队列                                手动创建串行队列                              主队列

同步(sync)      没有开启新线程/串行执行任务         没有开启新线程/串行执行任务       没有开启新线程/串行执行任务(卡死)

异步(async)    有开启新线程/并发执行任务              有开启新线程/串行执行任务           没有开启新线程/串行执行任务

(22)延迟执行

(a)ios常见的延迟执行有2种方式

(I)调用NSObject的方式

[self performSelector:@selector(run) withObject:nil afterDelay:2.0];//2秒后再调用self的run方法

(2)使用GCD函数

dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(2.0*NSEC_PER_SEC)),dispatch_get_main_queue(),^{

  //2秒后异步执行这里的代码....

});

(23)一次性代码

(I)使用dispatch_once函数能保证某段代码在程序运行过程中只被执行1次

(2)static dispatch_once_t onceToken;

dispatch_once(&onceToken,^{

  //只执行1次的代码(这里默认是线程安全的)

});

(24)队列组

(a)有这么1种需求:

(I)首先:分别异步执行2个耗时的操作

(II)其次:等2个异步操作都执行完毕后,再回到主线程执行操作

如果想要快速高效地实现上述需求,可以考虑用队列组

39.单例模式

(1)单利模式在ARC\MRC环境下的写法有所不同,可以用宏判断是否为ARC环境

#if __has_feature(objc_arc)

40.NSOperation

(1)NSOperationde的作用:配合使用NSOperation和NSOperationQueue也能实现多线程编程

(2)NSOperation和NSOperationQueue实现多线程的具体步骤

(I)先将需要执行的操作封装到一个NSOperation封装到一个NSOperation对象中

(II)然后将NSOperation对象添加到NSOperationQueue中

(III)系统会自动将NSOperationQueue中的NSOperation取出来

(III)将取出的NSOperation中封装放到的操作放到一个新线程中执行。

(3)NSOperation的子类

(a)NSOperation是一个抽象类,并不具备封装操作的能力,必须使用它的子类

(b)使用NSOperation子类的方式有3种

(I)NSInvocationOperation

(II)NSBlockOperation

(III)自定义子类继承NSOperation,实现内部相应的方法。

(4)NSInvocationOperation

(I)创建NSInvocationOperation对象

-(id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;

(II)调用start方法开始执行操作

-(void)start;

一旦执行操作,就会调用target的sel方法

(IV)注意:默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作。

(V)只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作。

(5)NSBlockOperation

(a)创建NSBlockOperation对象

+(id)blockOperationWithBlock:(void(^)(void))block;

(b)通过addExecutionBlock:方法添加更多的操作

-(void)addExecutionBlock:(void(^)(void))block;

注意:只要NSBlockOperation封装的操作数>1,就会异步执行操作

(6)NSOperationQueue

(a)NSOperationQueue的作用:

(I)NSOperation可以调用start方法来执行任务,但默认是同步执行的

(II)如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作

(b)添加操作到NSOperationQueue中

-(void) addOperation:(NSOperation*)op;

-(void)addOperationWithBlock:(void(^)(void))block;

(7)并发数

(a)什么是并发数:同时执行的任务数。比如,同时开3个线程执行3各任务,并发数就是3。例: queue.maxConcurrentOperationCount=3;

(8)队列的取消、暂停、恢复

(a)取消队列的所有操作

-(void)cancelAllOperations;

提示:也可以调用NSOperation的-(void)cancel方法取消单个操作

(b)暂停和恢复队列

-(void)setSuspended:(BOOL)b;//YES代表暂停队列,NO代表恢复队列

(9)操作优先级

(a)设置NSOperation在Queue中的优先级,可以改变操作的优先级

-(NSOperationQueuePriority)queuePriority;

-(void) setQueuePriority:(NSOperationQueuePriority)p;

(b)优先级的取值

(I)NSOperationQueuePriorityVeryLow=-8L;

(II)NSOperationQueuePriorityLow=-4L;

(III)NSOperationQueuePriorityNormal=0;

(IV)NSOperationQueuePriorityHigh=4;

(V)NSOperationQueuePriorityVeryHigh=8;

(10)操作依赖

(a)NSOperation之间可以设置依赖来保证执行顺序

(b)比如一定要操作执行完后,才能执行操作B可以这么写

[operationB addDependency:operationA];//操作B依赖于操作A

(c)可以在不同queue的NSOperation之间创建依赖关系

(d)注意:不能相互依赖

41.SDWebImage框架:用于处理图片下载:https://github.com/rs/SDWebImage