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); View Code27.打開網絡風火輪
UIApplication.sharedApplication().networkActivityIndicatorVisible=true; View Code28. 讀取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"); View Code29.畫兩個矩形
let rect1=CGRectMake(30, 50, 200, 200);let view1=UIView(frame:rect1);view1.backgroundColor=UIColor.brownColor();let rect2=CGRectMake(50, 80, 200, 200);let view2=UIView(frame:rect2);view2.backgroundColor=UIColor.greenColor();self.view.addSubview(view1);self.view.addSubview(view2); View Code30. 按鈕
override func viewDidLoad() {super.viewDidLoad()// Do any additional setup after loading the view, typically from a nib.let rect1=CGRectMake(30, 50, 200, 200);let view1=UIView(frame:rect1);view1.backgroundColor=UIColor.blueColor();self.view.addSubview(view1);let btAdd=UIButton(frame:CGRectMake(30, 350, 80, 30));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(120, 350, 80, 30));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(210, 350, 80, 30));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(60, 90, 200, 200);let view3=UIView(frame:rect);view3.backgroundColor=UIColor.redColor();view3.tag=1;self.view.addSubview(view3);}func bringViewBack(sender:UIButton!){let view=self.view.viewWithTag(1);self.view.sendSubviewToBack(view!);}func removeView(sender:UIButton!){let view=self.view.viewWithTag(1);view?.removeFromSuperview();} View Code31.給圖像視圖添加邊框效果、圓角效果、陰影效果
let image=UIImage(named:"120");let imageView=UIImageView(image:image);imageView.frame=CGRectMake(24, 80, 272, 410);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=10;imageView.layer.borderColor=UIColor.lightGrayColor().CGColor;self.view.addSubview(imageView); View Code32.UIView視圖的漸變效果
let rect=CGRectMake(60, 120, 200,200);let gradientView=UIView(frame:rect);let gradientLayer=CAGradientLayer();gradientLayer.frame=gradientView.framelet 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); View Code33.UIView視圖的紋理填充
let image=UIImage(named: "120");let patternColor=UIColor.init(patternImage:image!);self.view.backgroundColor=patternColor; View Code34.CGAffineTransform放射變換的使用?
let rect=CGRectMake(30, 150, 200, 50);let view=UIView(frame:rect);view.backgroundColor=UIColor.brownColor();self.view.addSubview(view);var transform=view.transform;transform=CGAffineTransformRotate(transform, 3.14/4);view.transform=transform; View Code35.UITapGestureRecognizer手勢之單擊、長按、雙擊
override func viewDidLoad() {super.viewDidLoad()let rect=CGRectMake(30, 80, 200, 256);let imageView=UIImageView(frame: rect);let image=UIImage(named: "120");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=2;guesture2.numberOfTouchesRequired=1;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);} View Code36打電話
(1)使用UIApplication 的openUrl方法實現
View Code37.多線程
(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=0; i<10000; 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); } View Code(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=0; i<1000; i++) {NSLog(@"test- %d-%@",i,[NSThread currentThread].name);if(i==50){[NSThread exit];//線程退出,等同于return; }}NSLog(@"test- 結束--%@",[NSThread currentThread].name); } View Code(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; } View Code(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
?
轉載于:https://www.cnblogs.com/heisaijuzhen/p/5417183.html
總結
- 上一篇: Linux系统编程11:进程入门之详细阐
- 下一篇: (计算机组成原理)第五章中央处理器-第四