ラベル OS X の投稿を表示しています。 すべての投稿を表示
ラベル OS X の投稿を表示しています。 すべての投稿を表示

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年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

2014年2月15日土曜日

Rubyバージョン管理ツールを導入する

OS Xで利用可能なRubyバージョン管理ツールは他にもあるが、ここでは個人的に最も使い勝手の良いと思われるrbenvの導入方法について説明する。

rbenvをインストールする。
$ brew install rbenv
$ rbenv -v
rbenv 0.4.0

ruby-buildをインストールする(PATH設定については、通常Homebrewを使ってインストールする場合は不要であるため、必要に応じて設定する)。
$ brew install ruby-build
$ echo 'export RBENV_ROOT="$HOME/.rbenv"' >> ~/.bashrc
$ echo 'export PATH="$RBENV_ROOT/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
$ source ~/.bashrc

readlineとopensslをインストールする(opensslについては、通常ruby-buildパッケージインストール時に一緒にインストールされるため、必要に応じてインストールする)。
$ brew install readline
$ brew install openssl

インストール可能なRubyのバージョンを確認する。
$ rbenv install -l

1.9.3-p484をインストールする。
$ CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 1.9.3-p484
$ rbenv rehash

2.0.0-p353をインストールする。
$ CONFIGURE_OPTS="--with-readline-dir=`brew --prefix readline` --with-openssl-dir=`brew --prefix openssl` --with-gcc=clang" rbenv install 2.0.0-p353
$ rbenv rehash

インストールされているRubyのバージョンを確認する。
$ rbenv versions
* system (set by /Users/hogeuser/.rbenv/version)
  1.9.3-p484
  2.0.0-p353

使用するRubyのバージョンを切り替える。
$ rbenv global 2.0.0-p353
$ rbenv versions
  system
  1.9.3-p484
* 2.0.0-p353 (set by /Users/hogeuser/.rbenv/version)

使用中のRubyのバージョンを確認する。
$ rbenv version
2.0.0-p353 (set by /Users/hogeuser/.rbenv/version)
$ ruby -v
ruby 2.0.0p353 (2013-11-22 revision 43784) [x86_64-darwin13.0.2]

2014年1月13日月曜日

Objective-Cで定数を定義する

ヘッダーファイルにおいて、#define(マクロ)を使って、(公開/非公開に関わらず)全ての定数にプレフィックスkをつけて定義しているコードを見かけることがあるが、下記理由から個人的にはあまり良くないのではないかと思っている。
  • 型情報がない
  • ヘッダーファイルインポート条件によっては、名前衝突により開発者が意図しないファイルにおいても定数置換が行われてしまう危険性がある

実際のところ、私は下記のように定数定義を行っている。

外部に公開する定数

  • extern constを付与
  • 定数にはプレフィックスとしてクラス名をつける(名前衝突を避けるため)

内部でのみ使用する定数

  • static constを付与
  • 定数にはプレフィックスとしてkをつける(よく見かけるパターン)

コーディング例

以下は、BLGClassAクラスにおいて外部に公開する定数を定義、BLGClassBクラスにおいて内部で使用する定数を定義、して利用する場合の例。


動作確認

コンパイル/リンクして実行。


2013年10月28日月曜日

Homebrewをアンインストールする

デフォルト設定で使っている場合は、下記を実行してHomebrewをアンインストールする。
$ brew doctor
$ brew update
$ git clone https://gist.github.com/1173223.git
$ cd 1173223/
$ chmod u+x uninstall_homebrew.sh
$ sh ./uninstall_homebrew.sh

必要に応じて、さらに下記を実行する。
$ rm -rf /usr/local/Cellar /usr/local/.git && brew cleanup

[参考URL]
How do I uninstall Homebrew?

2013年9月9日月曜日

Node.jsバージョン管理ツールを導入する

OS Xで利用可能なNode.jsバージョン管理ツールは複数あるが、ここでは個人的に最も使い勝手の良いと思われるnodebrewの導入方法について説明する。

プロキシ環境下にある場合は下記の通りプロキシ設定する。
$ vim ~/.bashrc
$ source ~/.bashrc

~/.bashrc
# proxy
export http_proxy="http://proxy.example.com:8080"
export https_proxy="http://proxy.example.com:8080"

nodebrewをインストールする。
$ curl -L git.io/nodebrew | perl - setup

PATHを通す。
$ vim ~/.bashrc
$ source ~/.bashrc

~/.bashrc
# nodebrew
NODEBREW_ROOT=$HOME/.nodebrew
export NODBREW_ROOT
# PATH
PATH=$PATH:${NODEBREW_ROOT}/current/bin

動作確認する。
$ nodebrew -v
nodebrew 0.6.3

Node.jsの最新安定版をインストールしてみる。
$ nodebrew ls-remote
$ nodebrew install-binary stable
fetch: http://nodejs.org/dist/v0.10.18/node-v0.10.18-darwin-x64.tar.gz

使用するNode.jsのバージョンを指定する。
$ nodebrew use v0.10.18
$ node -v
v0.10.18


補足

私の環境では.bash_profileで.bashrcファイルを読み込むようにしている。

~/.bash_profile
source ~/.bashrc

2013年4月26日金曜日

Node.jsをアンインストールする

OS X用インストーラ(.pkg)を使ってインストールしたNode.jsをアンインストールする。


はじめに削除すべきディレクトリ、ファイルを確認する。


/usr/local/bin(下記ファイルを削除する。モジュール導入環境によって異なる。)
lrwxr-xr-x    express -> ../lib/node_modules/express/bin/express
-rwxr-xr-x    node
-rwxr-xr-x    node-waf
lrwxr-xr-x    npm -> ../lib/node_modules/npm/bin/npm-cli.js

/usr/local/include(下記ディレクトリを削除する)
drwxr-xr-x    node

/usr/local/lib/dtrace(本ディレクトリごと削除する)
-rw-r--r--    node.d

/usr/local/lib/node(本ディレクトリごと削除する)
drwxr-xr-x    wafadmin

/usr/local/lib/node_modules(本ディレクトリごと削除する。モジュール導入環境によって異なる。)
drwxr-xr-x    express
drwxr-xr-x    npm

/usr/local/share/man/man1(下記ファイルを削除する)
-rw-r--r--    node.1

/var/db/receipts(下記ファイルを削除する)
-rw-r--r--    org.nodejs.node.npm.pkg.bom
-rw-r--r--    org.nodejs.node.npm.pkg.plist
-rw-r--r--    org.nodejs.pkg.bom
-rw-r--r--    org.nodejs.pkg.plist

~/(下記ディレクトリを削除する。プロキシ等を設定している場合は.npmrcファイルも削除する。)
drwxr-xr-x    .node-gyp
drwxr-xr-x    .npm
drwxr-xr-x    .sourcemint


実際に削除を行う。


有用なスクリプトがあるので利用する。
$ curl -ks https://gist.github.com/nicerobot/2697848/raw/uninstall-node.sh
$ chmod u+x uninstall-node.sh 
$ ./uninstall-node.sh 
$ rm uninstall-node.sh 
[参考URL]Mac OS X uninstall script for packaged install of node.js

上記スクリプトの対象となっていないディレクトリ・ファイルを手動で削除する(プロキシ等を設定している場合は.npmrcファイルも要手動削除)。
$ sudo rm -rf /usr/local/include/node
$ sudo rm -rf /usr/local/lib/dtrace
$ rm -rf ~/.node-gyp
$ rm -rf ~/.npm
$ rm -rf ~/.sourcemint

2012年11月1日木曜日

Node.jsをインストールする


Node.jsのダウンロードサイトからインストーラファイルであるOS X Installer (.pkg)をダウンロードする。
nodeが/usr/local/bin/nodeに、npmが/usr/local/bin/npmにインストールされる。

念のため、/usr/local/binがパスにあることを確認しておく。
$ echo $PATH

nodeのバージョンを確認する。
$ node -v
v0.8.14

npmのバージョンを確認する。
$ npm -v
1.1.65