2018年4月30日 星期一

NSThread, GCD

NSThread

有三種方式可以開Thread
  1. NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(test:) object:nil];
  2. [NSThread detachNewThreadSelector:@selector(test:) toTarget:self withObject:@"分离子线程"];
    [self performSelectorInBackground:@selector(test:) withObject:@"后台线程"];

第一種方式可以取得該線程的instance,也可以設定Thread Priority,但要手動啟動線程
第二三種方式直接開啟線程,但無法取得instance
performSelector是比較早期的API,跟NSThreadㄧ樣呼叫一次就開一個線程 
目前Object-C大多使用GCD或是NSOperationQueue,這兩個API會自行管理線程數量



GCD

分作兩種模式
  1. dispatch_async :非同步
  2. dispatch_sync:同步
同步模式下會先等待Block裡面的動作執行完,才繼續往下跑
個人感覺有點類似C#的async Task 搭配 await語法,會把工作丟給別的Thread去做,但會等工作做完才繼續動作

實際上使用dispatch_sync後,發現動作並沒有在其他Thread執行,而是使用main thread,爬文之後發現有人在討論這個問題



也就是說因為main queue是serial queue,呼叫dispatch_sync必定導致線程block住,無所謂執行block內工作的線程,所以程式會直接使用main queue執行,節省開線程的資源

如果今天是在背景呼叫dispatch_sync把工作丟給main queue,就會有線程切換的動作

簡單來說 dispatch_sync 不會開新線程,但在特定情況下,會有線程切換

另外使用dispatch_async也不一定呼叫幾次就開啟多少線程,程式會自行控制
推測應該跟C#一樣使用thread pool的概念
有文章說線程上限66個,serial 與 concurrent共用這數量


使用GCD要小心Block的問題,千萬不要在同步模式(dispatch_sync) 下丟一個Block給自己的線程,自己等自己會卡住

dispatch_queue 可以分為兩種,serial queue與concurrent queue
main_queue:serial queue
global_queue:於concurrent queue
用dispatch_queue_t可以自行宣告,自行決定類型

GCD使用方法



當函式使用非同步模式,又必須回傳其運作結果時,需要使用dispatch_semaphore_t
類似於async await,之後會詳細描述

http://www.iosxxx.com/blog/2016-06-02-GCD那些事.html

2018年4月26日 星期四

Object-C Serialization

Object-C的Serialization不像C#一樣方便
需要在原本的class中寫Encode和Decode方法
寫法如下:

Object-C Extensions

Extension 可以把一個很大的Class拆分,有點類似Category

Extension與Category的差別

  1. Extension中可以定義變數.屬性.方法,Category只能定義方法
  2. Extension不能按照功能或層級來自定名稱(匿名),Category可以在Class後的小括弧內定義
  3. Extension定義出來的Method必須在原Class的Implement中實作 ,Category有自己的.m檔

Extension大部分使用在宣告私有的屬性跟方法,因為Method在.h檔都可以被外部呼叫,如果想宣告一個私有方法,一個方式是只寫Implement,另一個方式就是在.m檔底下使用Extension

Extension使用方法如下:



2018年4月25日 星期三

Cocoa control - Menu

以下解說Cocoa Menu綁定Method的方法





在StoryBoard產生Menu物件之後 ,將Menu點擊動作與其ViewController綁定的流程如下:
1.先在ViewController中寫好要執行的IBAction


2.在Menu選單上按下右鍵,拖曳至上方橘色方塊( First Responder),會出現所有事件的清單

    選擇剛剛寫好的IBAction,就成功綁定了,當Menu按下後會執行Menu的IBAction,再呼叫原本的Method

    First Responder表示當前Window的第一回應對象,其對象必須是NSView或其子集,概念有點像WPF裡面keyBinding,會依當前Focus對象不同,執行不同的動作

    NSView要執行鍵盤事件,一定要先成為First Responder