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
IOS随机随学的更多相关文章
- iOS随机页面NSClassFromString
NSString *className = self.classNameArray[randomNumber]; Class viewClass = NSClassFromString(class ...
- iOS随机生成数字
有时候我们需要在程序中生成随机数,但是在Objective-c中并没有提供相应的函数,好在C中提供了rand().srand().random().arc4random()几个函数.那么怎么使用呢?下 ...
- iOS随机颜色
#import <UIKit/UIKit.h> @interface UIColor (RandomColor) +(UIColor *) randomColor; @end #impor ...
- iOS开发- 速学Swift-中文概述
Swift是什么? Swift是苹果于WWDC 2014公布的编程语言,这里引用The Swift Programming Language的原话: Swift is a new programmin ...
- Unity随机随学
1.什么是渲染管道? 是指在显示器上为了显示出图像而经过的一系列必要操作.渲染管道中的步骤很多,都要将几何物体从一个坐标系中变换到另一个坐标系中去. 主要步骤有: 本地坐标->视图坐标-> ...
- ios 随机色 宏定义
#define RGBColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1] #d ...
- iOS --随机打乱一个数组的顺序 获得一个新的数组
NSArray* arr = @[@"1",@"2",@"3"]; arr = [arr sortedArrayUsingComparato ...
- ios开发网络学八:NSURLSession相关代理方法
#import "ViewController.h" @interface ViewController ()<NSURLSessionDataDelegate> /* ...
- iOS GCD NSOperation NSThread等多线程各种举例详解(拷贝)
2年多的iOS之路匆匆而过,期间也拜读来不少大神的博客,近来突然为自己一直做伸手党感到羞耻,是时候回馈社会.回想当年自己还是小白的时候,照着一些iOS多线程教程学,也只是照抄,只知其然.不知其所以然. ...
随机推荐
- Servlet异步上传文件
这里需要用到插件ajaxfileupload.js,jar包:commons-fileupload-1.3.2.jar,commons-io-2.5.jar 注意红色部分的字!!!! 1.创建一个we ...
- MyEclipse 点击 部署 按钮 无效
找到MyEclipse的工作路径,我的是"D:\Workspace",到这个目录中去"\.metadata\.plugins\org.eclipse.core.runti ...
- Android组件安全
今天在看有关Android组件安全的东西 1.Activity Android系统组件在指定Intent过滤器(intent-filter)后,默认是可以被外部程序(签名不同,用户ID不同)访问的,在 ...
- 使用MyBatis对表执行CRUD操作
一.使用MyBatis对表执行CRUD操作——基于XML的实现 1.定义sql映射xml文件 userMapper.xml文件的内容如下: <?xml version="1.0&quo ...
- SQLite 加密 -- SQLCipher
SQLite3 插件 github 下载地址 插件配置步骤地址 购买地址 其他加密方式介绍 SQLCipher API 地址 前言 应用使用 SQLite 来存储数据,很多时候需要对一部分的数据进行加 ...
- 【转】24Cxx 系列EEPROM通用程序及应用
关于I2C 学习的时候介绍得最多的就是24C02 这里存储EEPROM了,但学的时候基本只是讲讲简单的I2C 的总线数据传输而已,即使先gooogle上搜索也绝大部分这这样的文章,很少有说到如何在实际 ...
- android 生命周期
引入android生命周期概念来做前端的hash切换页面的思路: 1. page manager来管理多个page(一对多的关系); 2. route:URL <-> Page; 3. P ...
- IT行业常谈的优雅
起因 前几天在群里和以前一起在成都培训的同学谈论到了求职, 有一位朋友说他在某家外包公司试用失败了, 然后我说了句:不要去外包公司.即使工资高一点. 其实说的时候也没考虑到他本人的处境, 毕竟还房贷资 ...
- jquery toggle方法
$("#myDiv").toggle(function () { alert(1); }, function () { alert(2); }); 某种需求下可以替代click事件 ...
- 如何消除MyEclipse导入jQuery库后出现的错误标记
由于MyEclipse提供比较严谨的js校验功能,因此jQuery等前端框架导入到MyEclipse后均会提示错误,比较难看,如果要将校验去掉可以遵循下面步骤:1.点击菜单“MyEclipse”-&g ...