2015年5月23日土曜日

GCDについて情報整理する

歴史的なことも含めてGCDに関する情報を整理しておく。


GCDの歴史

  • Mac OS X 10.6(Snow Leopard)以降、iOS 4.0以降で利用可能
  • OS X 10.8(Mountain Lion)、iOS 6.0以降では、GCDオブジェクト(Dispatch Queue)もARCの管轄下に入るようになった(実際にはGCDだけでなくXPCも)
  • OS X 10.10(Yosemite)、iOS8.0 からQoS(Quality of Service)の概念が導入された


ディスパッチキューの利用


ディスパッチキューの利用には大きく分けて2つの方法がある

  1. dispatch_queue_create関数を使ってディスパッチキューを自分で生成する
  2. システムが標準で提供しているディスパッチキューを取得する

1. dispatch_queue_create関数を使ってディスパッチキューを自分で生成する

  • 開発者はシリアルキューとコンカレントキューを生成できる
  • コンカレントキューを自分で生成するケースは稀
  • OS X v10.7、iOS 4.3以降から第2引数にNULL以外を指定できるようになった

1.1. シリアルキューを生成する場合
dispatch_queue_t mySerialDispatchQueue 
= dispatch_queue_create("com.example.MySerialDispatchQueue", DISPATCH_QUEUE_SERIAL);
// または、下記の通り、第2引数にNULLを指定してもよい。
// ただし、個人的には明示的に定数指定している上記の書き方の方がいいと思う。
//dispatch_queue_t mySerialDispatchQueue 
//= dispatch_queue_create("com.example.MySerialDispatchQueue", NULL);

1.2. コンカレントキューを生成する場合
dispatch_queue_t myConcurrentDispatchQueue 
= dispatch_queue_create("com.example.MyConcurrentDispatchQueue", DISPATCH_QUEUE_CONCURRENT);


2. システムが標準で提供しているディスパッチキューを取得する

  • システムが標準で提供しているディスパッチキューは2種類ある(Main Dispatch QueueとGlobal Dispatch Queue)
  • アプリのどこからでも利用できる

2.1. Main Dispatch Queue
  • メインスレッドで実行されるシリアルキュー(メインスレッドは1つしかないため)
  • 実際にはメインスレッドで実行されるデフォルトのRunLoopで処理される
  • Main queue is access queue for UI
dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();

2.2. Global Dispatch Queue
  • コンカレントキュー
  • 実行優先度別に4種類(従来方式)または5種類(QoS方式)ある
  • 2015年5月現在においてバックワードコンパチを考慮(例えばiOS7.xをサポート)する場合は必然的に従来方式を採用することになる
// OS X 10.10(Yosemite)、iOS8.0以前でも以降でも利用できる
// 第2引数は0固定

dispatch_queue_t globalDispatchQueuePriorityHigh 
= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

dispatch_queue_t globalDispatchQueuePriorityDefault 
= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_queue_t globalDispatchQueuePriorityLow 
= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

dispatch_queue_t globalDispatchQueuePriorityBackground 
= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

// OS X 10.10(Yosemite)、iOS8.0以降でしか利用できない
// 第2引数は0固定

// 基本的にはQoSに関する明確な意思を決めて
// QOS_CLASS_DEFAULT以外を選択するのが良さげ。
// また、QOS_CLASS_DEFAULTについては下記の通り。
// Ordered between UI and non-UI QoS
// Not intented as a work classification

dispatch_queue_t globalDispatchQueueQosInteractive 
= dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0);

dispatch_queue_t globalDispatchQueueQosInitiated 
= dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0);

dispatch_queue_t globalDispatchQueueQosDefault 
= dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);

dispatch_queue_t globalDispatchQueueQosUtility 
= dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);

dispatch_queue_t globalDispatchQueueQosBackground 
= dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0);



コード例


ワーカスレッドがシリアルの場合
dispatch_queue_t mySerialDispatchQueue 
= dispatch_queue_create("com.example.MySerialDispatchQueue", DISPATCH_QUEUE_SERIAL);
    
dispatch_async(mySerialDispatchQueue, ^{
    // ワーカスレッド(シリアル)
    // 重い処理をここに書く
    
    dispatch_async(dispatch_get_main_queue(), ^{
        // メインスレッド(シリアル)
        // UI処理をここに書く
    });
    
});

ワーカスレッドがコンカレントの場合
//dispatch_queue_t globalDispatchQueuePriorityDefault 
//= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(globalDispatchQueuePriorityDefault, ^{
    // ワーカスレッド(コンカレント)
    // 「コンカレント実行されても問題ない」重い処理をここに書く
    
    dispatch_async(dispatch_get_main_queue(), ^{
        // メインスレッド(シリアル)
        // UI処理をここに書く
    });
    
});

2015年5月17日日曜日

CocoaPodsを使ってAFNetworkingを導入する

導入対象プロジェクト(今回の場合はPodsSample.xcodeproj)は閉じておく。
プロジェクトファイルがあるディレクトリまで移動後、Podfileを生成する。
$ cd /path/to/PodsSample
$ pod init

Podfileを編集する。
$ open -a Xcode Podfile

Podfile
# Uncomment this line to define a global platform for your project
# platform :ios, '6.0'
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'

target 'PodsSample' do
  pod 'AFNetworking', '~>2.5.3'
end

target 'PodsSampleTests' do

end


Podfileを保存して閉じた後、pod installを実行する。
$ rm Podfile.lock
$ pod install --verbose

以降は常にプロジェクトではなく、ワークスペースを開いて使う。
$ ls -l
(下記は抜粋表示)
Podfile
Podfile.lock
Pods
PodsSample
PodsSample.xcodeproj
PodsSample.xcworkspace
PodsSampleTests

$ open PodsSample.xcworkspace


CocoaPods管理のライブラリを更新する際は下記を実行する。
$ pod update


2015年5月16日土曜日

CocoaPodsをインストールする

使用中のRuby及びgemのバージョンを確認する。
$ rbenv version
2.2.0 (set by /Users/hogeuser/.rbenv/version)
$ gem -v
2.4.7

CocoaPodsをインストールする。
$ gem install cocoapods
$ rbenv rehash
$ pod setup --verbose


補足


「gem install cocoapods」により"追加で"インストールされたgem
activesupport (4.2.1)

claide (0.8.1)
cocoapods (0.37.1)
cocoapods-core (0.37.1)
cocoapods-downloader (0.9.0)
cocoapods-plugins (0.4.2)
cocoapods-trunk (0.6.0)
cocoapods-try (0.4.4)
colored (1.2)
escape (0.0.4)
fuzzy_match (2.0.4)
i18n (0.7.0)

molinillo (0.2.3)
nap (0.8.0)
netrc (0.7.8)

thread_safe (0.3.5)
tzinfo (1.2.2)
xcodeproj (0.24.1)

インストールするCocoaPodsのバージョンを指定する場合(RubyGemsの仕様通り)
$ gem install cocoapods --version "=0.36.4"

「pod setup」ではそれなりに時間がかかるので根気よく待つ。

2015年4月29日水曜日

32bit EFIブートファイルを作成する

WindowsタブレットPC等で採用されているCPU(Intel Atom: xx Trail)は基本的に32bitアーキテクチャであり、最近は例外なくファームウェアとしてUEFIが採用されていることから、この類のものにLinuxをインストールしたい場合は、別途32bit版(U)EFIファイルを用意する必要がある。

環境
  • Ubuntu Server 14.04.2 LTS x64

作業ディレクトリを作成
$ mkdir ~/tmpwork
$ cd ~/tmpwork

必要なパッケージをインストール
$ sudo apt-get update -y
$ sudo apt-get install -y git build-essential
$ sudo apt-get install -y bison libopts25 libselinux1-dev autogen m4 autoconf help2man libopts25-dev flex libfont-freetype-perl automake autotools-dev libfreetype6-dev texinfo

GRUB 2のソースを落としてきてmake
$ git clone git://git.savannah.gnu.org/grub.git
$ cd grub
$ ./autogen.sh
$ ./configure --with-platform=efi --target=i386 --program-prefix=''
$ make

EFIファイルを作成
$ cd grub-core
$ sudo ../grub-mkimage -d . -o bootia32.efi -O i386-efi -p /boot/grub ntfs hfs appleldr boot cat efi_gop efi_uga elf fat hfsplus iso9660 linux keylayouts memdisk minicmd part_apple ext2 extcmd xfs xnu part_bsd part_gpt search search_fs_file chain btrfs loadbios loadenv lvm minix minix2 reiserfs memrw mmap msdospart scsi loopback normal configfile gzio all_video efi_gop efi_uga gfxterm gettext echo boot chain eval

作成したEFIファイルを作業ディレクトリ直下にコピーしておく
$ cp bootia32.efi ~/tmpwork


[参考URL]
Instructions to install Ubuntu 14.10 on ASUS EeeBook X205TA
UEFIBooting - Community Help Wiki

2015年4月26日日曜日

Ubuntu ServerインストーラをUSBメモリに書き込む

環境
  • Ubuntu Server 14.04.2 LTS x64

isoイメージファイルをダウンロード
$ wget http://releases.ubuntu.com/14.04/ubuntu-14.04.2-server-amd64.iso
$ md5 ubuntu-14.04.2-server-amd64.iso 
MD5 (ubuntu-14.04.2-server-amd64.iso) = 83aabd8dcf1e8f469f3c72fff2375195

isoファイルからimgファイルに変換
$ hdiutil convert -format UDRW -o ubuntu-14.04.2-server-amd64.img ubuntu-14.04.2-server-amd64.iso
$ mv ubuntu-14.04.2-server-amd64.img.dmg ubuntu-14.04.2-server-amd64.img

USBメモリを接続してディスク番号を確認
$ diskutil list
$ df -h

USBメモリをアンマウントした上で、rawデバイス指定でimgファイルを書き込む
(下記はディスク番号が「2」の場合)
$ sudo diskutil unmountDisk /dev/disk2
$ sudo dd bs=1m if=ubuntu-14.04.2-server-amd64.img of=/dev/rdisk2
$ sudo diskutil eject /dev/disk2


[参考URL]
How to create a bootable USB stick on OS X | Ubuntu

2015年3月7日土曜日

Javaの設定を行う

現在インストールされているJDKを確認する(私の環境ではJDK6、7、8がインストール済み)。
$ /usr/libexec/java_home -V

JDK7をJAVA_HOMEとして設定する。
$ vim ~/.bashrc
$ less ~/.bashrc
(関連箇所を抜粋)
export JAVA_HOME=`/usr/libexec/java_home -v 1.7`

必要に応じてJavaVMのオプションを設定する。例えば下記の通り。
$ vim ~/.bashrc
$ less ~/.bashrc
(関連箇所を抜粋)
export JAVA_OPTS="-Dfile.encoding=UTF-8"
# または
#export JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF-8"

最後に~/.bashrcを再読み込み
$ source ~/.bashrc