SlideShare a Scribd company logo
Objective-C
de
lambda
松浦 明彦
@matu_ani
1
13年9月4日水曜日
自己紹介
• コップ本読んでる途中な程度
• 札幌C++勉強会メンバー(最年長w)
•

「プログラミングの魔導少女」:巻末記事

•
•

「C++の設計と進化」(通称:D&E)

• 監修メンバー
「ストラウストラップのプログラミング入門」
(通称:鈍器w)

• ジャズと酒が趣味、シングルパパです。
2
13年9月4日水曜日
お話しすること・ねらい
• Objective-Cの紹介がてら、関数型つなが
りでObjective-Cのラムダ式(Blocks)に
ついてお話します。

•

めざせBlocks完全制覇!!

• 実装・シンタックス寄り、現場的なお話し
です。

• 関数型的なお話は殆どありません m(_ _)m
3
13年9月4日水曜日
もくじ
• Objective-C 文法基礎
• Objective-C Blocks基礎
• Objective-C Blocks応用
• C++とBlocks
4
13年9月4日水曜日
Objective-C
文法基礎
さらっと流します...

5
13年9月4日水曜日
Objective-Cとは
• C言語にオブジェクト指向機能を追加:☓
• Smalltalk風 Object Systemの言語環境にて、C
言語も使うことが出来る:○

• Cの言語仕様自体には、何も足さない何も引かない。

6
13年9月4日水曜日
Objective-Cとは
• C言語にオブジェクト指向機能を追加:☓
• Smalltalk風 Object Systemの言語環境にて、C
言語も使うことが出来る:○

• Cの言語仕様自体には、何も足さない何も引かない。
スクリプト言語並の動的言語と静的型付
け言語が共存するハイブリッドな環境
6
13年9月4日水曜日
Smalltalk 例
"initializeメッセージをaMyObjectに送信"
aMyObject initialize.
"引数30のsetSizeメッセージをaSquareに送信"
aSquare setSize : 30.
"オブジェクト「3」にセレクタ「+」を引数「4」で送信"
total := 3 + 4.

7
13年9月4日水曜日
Objective-Cでのメッセ
ージ送信

• メソッド呼び出しは、メッセージ(セ
レクタ)送信の結果である。
// 単項メッセージ(引数なし)
[receiver msg];
// receiver->msg();
// 引数付きメッセージ
val = [receiver msg: arg1 with: arg2];
// val = receiver->msg( arg1, arg2 );
8
13年9月4日水曜日
Objective-Cでのメッセ
ージ送信

• メソッド呼び出しは、メッセージ(セ
レクタ)送信の結果である。
// 単項メッセージ(引数なし)
[receiver msg];
// receiver->msg();

[] で囲う
メッセージキーワード

// 引数付きメッセージ

val = [receiver msg: arg1 with: arg2];
// val = receiver->msg( arg1, arg2 );
8
13年9月4日水曜日
クラスの宣言・定義
• クラスの宣言・定義には@コンパイラデ
ィレクティブを使う。

• 通常、宣言部を.hファイル、実装部を.m
ファイルに記述する。(一緒でもよい)

• #importは#includeと基本同じだが、二
重includeしない。
9
13年9月4日水曜日
#import <Foundation/Foundation.h>
// クラスの宣言
@interface MyClass : NSObject {
int val;
}
- (id)init;
+ (void)classMethod:(id)arg; // クラスメソッド
- (id)method:(NSObject*)arg1 with:(int)arg2;
@end
// 実装
@implementation MyClass
+ (void)classMethod:(id)arg {
// some operation
}
- (id)method:(NSObject*)arg1 with:(int)args2 {
return obj;
}
@end

10
13年9月4日水曜日
#import <Foundation/Foundation.h>
// クラスの宣言
@interface MyClass : NSObject {
int val;
}
- (id)init;
+ (void)classMethod:(id)arg; // クラスメソッド
- (id)method:(NSObject*)arg1 with:(int)arg2;
@end
// 実装
@implementation MyClass
+ (void)classMethod:(id)arg {
// some operation
}
- (id)method:(NSObject*)arg1 with:(int)args2 {
return obj;
}
@end

10
13年9月4日水曜日
制御構文
• if,while,for,とか、JavaやC++と同じ。
AlarmFake* f = [[AlarmFake alloc]init];
if( [f conformsToProtocol:@protocol(Alarm)]
{
// ・・・
}

11
13年9月4日水曜日

)
基礎編、もうちょい
• C/C++との共存
• メモリ管理について

12
13年9月4日水曜日
C/C++との共存
• 普通にC/C++が使える。
• C++を使う場合、.mでなく、.mmにす
る。(ていうか基本.mmにすべし)

• boostも使える。
• Xcode4.2のllvm-clangはC++11(一
部)も!
13
13年9月4日水曜日
#import <Foundation/Foundation.h>
#include <iostream>
#include <boost/shared_ptr.hpp>
class CppClass{
public:
C++のクラス
! CppClass(){}
! void print() const {
! ! std::cout << "CppClass::print" << std::endl;
! }
};
@interface ObjcClass : NSObject
- (void)print;
@end
Objective-Cのクラス
@implementation ObjcClass
- (void)print {
! NSLog(@"ObjcClass print");
}
@end
void boost_test(){
! boost::shared_ptr<CppClass> p(new CppClass);!
! ObjcClass* oc = [[ObjcClass alloc]init];!
! [oc print]; // ObjcClass print
! p->print(); // CppClass::print
}
14
13年9月4日水曜日
メモリ管理
• Objective-Cのクラスは静的には生成で
きない。必ずallocする。
MyObject* obj = [[MyObject alloc] init];
[obj method :arg with:10];

15
13年9月4日水曜日
参照カウンタ
• 難敵:retain,release,autorelease
MyObject* obj = [[MyObject alloc] init]; // 参照カウント1
[obj retain]; // 参照カウント2
NSLog(@"count=%d", [obj retainCount] ); // count=2
[obj release] ; // 参照カウント1
[obj release] ; // 参照カウント0,開放される
・・・
// メモリプールが有効なあいだ生きてる
MyObject* obj = [[[MyObject alloc] init] autorelease];
[obj retain]; // 参照カウント2、メモリプールの生き死に関わらず保持した
い!

16
13年9月4日水曜日
簡単にリークするw
• release忘れ
• retainしすぎ
• autorelease忘れ
• しかも、これらが絡み合うww
• ..... Appleが示した解決策は
17
13年9月4日水曜日
Automatic Reference
Counting (ARC)

• iOS5、MacOSX10.6から
• Xcode4.2ではデフォルト
• 参照カウンタ管理をコンパイル時に解決し
てくれる。ヽ(^。^)ノ
• retain/release/retainCount等は書かなく
ていい。
•

てか、書いたらコンパイルエラー orz

• GCとは別(GCもオプションであり)
18
13年9月4日水曜日
その他の機能
•
•
•
•
•
•
•
•
•

ランタイムシステム
プロパティ
プロトコル
カテゴリ
クラスエクステンション
クラスクラスタ
例外
GC
高速列挙

•

・・・などなど、あと、フレームワークには一切触れてません

19
13年9月4日水曜日
Objective-C
Blocks

20
13年9月4日水曜日
Blocks基礎

21
13年9月4日水曜日
Blocksって
• ようはラムダです。
•

ラムダ式のリテラル

• MacOSX 10.6/iOS 4.0以降
• AppleのC言語の拡張
•

http://www.open-std.org/jtc1/sc22/wg14/
www/docs/n1370.pdf

22
13年9月4日水曜日
Declaring a Block

•
•

シンタックスはCの関数ポインタと似ている。
^ を使う。
23

13年9月4日水曜日
Using a Block
void (^b1)(int) = ^(int x){NSLog(@"Hello Blocks %d",x);};
b1(100); // Hello Blocks 100
// パラメータ無しなら定義側は()を省略してもOK
void (^b2)() = ^{NSLog(@"Hello Blocks 2");};
b2(); // Hello Blocks 2

24
13年9月4日水曜日
パラメータにBlock
void blocks_caller( void (^f)(void) )
{
! f();
}
void blocks_test()
{
! blocks_caller( ^(){ NSLog(@"test1");} );
}

25
13年9月4日水曜日
Blocksどーよ
• 最近のCocoaAPI は積極的にBlockを

使う傾向にある(iCloud APIとか)。

• なんだかんだメモリ管理を意識。

Automatic Reference Counting
(ARC) のもとで使うのが良さそう。

• 過渡期っぽい.....が、今後は重要なプロ
グラミングスタイルと思われ。
26
13年9月4日水曜日
Blocks応用
といっても、
キャプチャとかBlockの寿命とかそのへん

27
13年9月4日水曜日
変数のキャプチャ
• ローカル変数、グローバル変数をBlock
内で使用可能

• ローカル変数はデフォルトで、イミュー
タブル、かつBlock構築時のコピー

28
13年9月4日水曜日
キャプチャの例
int g=999; // グローバル変数
・・・
int x = 100;
void (^b)() = ^(){NSLog(@"x=%d g=%d",x,g);};
b(); // x=100 g=999
x=200;
b(); // x=100(変わらず)
g=888;
b(); // x=100 g=888
29
13年9月4日水曜日
ミュータブルで共有なキャ
プチャ
__block int x=100;
void (^b)() = ^(){NSLog(@"x=%d g=%d", x++, g);};
b(); // x=100 g=999
b(); // x=101 g=999
x=200;
b(); // x=200 g=999

30
13年9月4日水曜日
クラスで使う
@interface testClass : NSObject{
int x_;
}
-(void) myprint;
-(void) print:(void(^)(int x))printer;
@end
@implementation testClass
-(void)print:(void (^)(int x))printer {
printer(x_);
}

testClass* t = [[testClass alloc]init];
[t print:^(int x){ NSLog(@"my printer x=%d", x);}];
31
13年9月4日水曜日
selfのキャプチャ
-(void)myprint { // testClassのメソッド
x_ = 100;
void(^b)()=^{ NSLog(@"x_=%d", x_);};
b(); // x_ = 100
x_ = 200;
b(); // x_ = 200 !!(コピーと違うの??)
// こう書いているのと同じ
}

void(^b2)()=^{ NSLog(@"testClass x_=%d", self->x_);};

• メンバー変数がキャプチャされているのではない
• selfがキャプチャされている!
32
13年9月4日水曜日
高階関数、部分適用
C#
Func<int, Func<int, int>> f = x => y => x + y;
Func<int, int> fc = f(1);
int x = fc(3); // 4 (1 + 3)

C++11
auto f = [](int x){ return [x](int y){return x+y;}; };
auto fc = f(1);
int x = fc(3); // 4 (1 + 3)

33
13年9月4日水曜日
Blockだと。。
void blocks_test()
{
! typedef int (^add_function)(int);
! add_function (^f)(int) =
! ! ! ! ! ^(int x){
! ! ! ! ! ! return Block_copy(^(int y){ return x+y;});
! !

! ! ! };

! add_function fc = f(1);
! NSLog(@"blocks_test() fc=%d", fc(3)); // 4 (1 + 3)
! Block_release(fc);
}

34
13年9月4日水曜日
Blocks大事なこと
• Blockの生存期間はそのスタックと同じ。
• スタック外で使うならコピーが必要。
•
•

Block_copy / Block_release
ただ、コピーしなくてもコンパイル通る(事が多い)し、
動くから恐ろしい。

• ARCのもとでは Block_copy /
Block_release 不要。

•

てかコンパイルエラーになる
35

13年9月4日水曜日
ARCありなら...
void blocks_test()
{
! typedef int (^add_function)(int);
! add_function (^f)(int) =
^(int x){return ^(int y){return x+y;};};
! add_function fc = f(1);
! NSLog(@"blocks_test() fc=%d", fc(3)); // 4 (1 + 3)
}

すっきり(^^)
36
13年9月4日水曜日
軽くまとめ
• ローカル変数のキャプチャはデフォルトで

イミュータブルかつBlock構築時のコピー。

• __block修飾されたローカル変数は、ミュー
タブルとなり、そのスタック内のblockで共
有される。

• Blockの寿命はスタックと同じ。スタック外
でも使いたければcopyが必要。

• ARCが吉
37
13年9月4日水曜日
BlocksとC++
実はここを一番話したかったという噂もw...

38
13年9月4日水曜日
C++11のfunction<T>
にBlockを
std::function<void(int)> f
= ^(int x){NSLog(@"Hello function!! x=%d",x);};
f(1); // Hello function!! x=1
f(2); // Hello function!! x=2

std::function<T>は、Blocks対応に書き換え
てあるのかな??

39
13年9月4日水曜日
簡易function作った
template<typename R, typename ...V>
struct my_function {
struct HolderBase{
virtual R run(V... arg)=0;
};
template<typename F>
struct Holder : HolderBase {
F f_;
Holder(F f):f_(f){}
virtual R run(V... arg) {
return f_(arg...);
}
};
boost::scoped_ptr<HolderBase> holder_;
template<typename F>
my_function(F f) : holder_(new Holder<F>(f) ){}
R operator()(V... arg) {
holder_->run(arg...);
}
};
40
13年9月4日水曜日
my_functionにも
my_function<void,int> mf(^(int x){NSLog(@"my_function!! x=%d",x);});
mf(100); // my_function!! x=100

• my_functionにBlocks固有のコードは無い。
• BlocksはObjC固有の型だが、C++のジェネリッ
ク型システムはそれを吸収した(とも言えるか
と)。

• 無論、std::functionは変更不要

。

(のはず)

41
13年9月4日水曜日
C++11 autoで型推論
// blockをautoで型推論
auto af = ^(int x){NSLog(@"Hello C++11 auto!! x=%d",x);};
af(5); // Hello C++11 auto!! x=5
// 高階関数も楽チン
auto f = ^(int x){ return ^(int y){ return x+y;};};
auto fc = f(1);
NSLog(@"Hello C++11 auto!! fc=%d",fc(3)); // fc=4

42
13年9月4日水曜日
C++11 autoで型推論
// blockをautoで型推論
auto af = ^(int x){NSLog(@"Hello C++11 auto!! x=%d",x);};
af(5); // Hello C++11 auto!! x=5
// 高階関数も楽チン
auto f = ^(int x){ return ^(int y){ return x+y;};};
auto fc = f(1);
NSLog(@"Hello C++11 auto!! fc=%d",fc(3)); // fc=4

やっぱC++かわいいw
42
13年9月4日水曜日
ご清聴
ありがとうございました

43
13年9月4日水曜日

More Related Content

PPTX
C#や.NET Frameworkがやっていること
PPTX
C# 9.0 / .NET 5.0
PPTX
C#言語機能の作り方
PDF
Lombok ハンズオン
PDF
Lombokのススメ
PPT
わんくま東京#38 LT 「Func&lt;> と ref / out 小咄」
PDF
とあるFlashの自動生成
PPT
C++でぼくが忘れがちなこと
C#や.NET Frameworkがやっていること
C# 9.0 / .NET 5.0
C#言語機能の作り方
Lombok ハンズオン
Lombokのススメ
わんくま東京#38 LT 「Func&lt;> と ref / out 小咄」
とあるFlashの自動生成
C++でぼくが忘れがちなこと

What's hot (15)

PDF
FirefoxOSで学ぶJavaScript作法
PDF
きつねさんでもわかるLLVM読書会amagasaki.rb第5章
PPTX
C# コンパイラーの書き換え作業の話
PPTX
final int をFINAL しやがれ!
PPT
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
PDF
Oss coding style
PDF
リテラル文字列型までの道
PDF
C言語の宣言読み方講座
PDF
Python と型ヒント (Type Hints)
PDF
静的型付け言語Python
PPTX
Python と型アノテーション
PPT
Start!! Ruby
PDF
マニアックなRuby 2.7新機能紹介
PDF
.NET系開発者から見たJava
PDF
Unity2015_No10_~UGUI&Audio~
FirefoxOSで学ぶJavaScript作法
きつねさんでもわかるLLVM読書会amagasaki.rb第5章
C# コンパイラーの書き換え作業の話
final int をFINAL しやがれ!
Php unit extensions_selenium2_testcaseによる結合試験でらくらくテスト♪
Oss coding style
リテラル文字列型までの道
C言語の宣言読み方講座
Python と型ヒント (Type Hints)
静的型付け言語Python
Python と型アノテーション
Start!! Ruby
マニアックなRuby 2.7新機能紹介
.NET系開発者から見たJava
Unity2015_No10_~UGUI&Audio~
Ad

Similar to Objectie-C de ラムダ (20)

KEY
Objc lambda
PDF
20130824 Lightweight Language "Go" @LL matsuri
PDF
20140822 Swift 勉強会 vol.3 - はぢめての Swift
PDF
マルチコア時代の並列プログラミング
PDF
dm-writeboost-kernelvm
PPTX
Emscriptenと不思議のダンジョン
PDF
今日から始めるGopher - スタートGo #0 @GDG名古屋
PDF
What's Cooking In Ruby 2.7
PDF
すごい constexpr たのしくレイトレ!
KEY
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
PPTX
Net fringejp2016
PDF
Scala conf2013
PDF
こわくないScala
PPTX
Seurity Camp Award 2016
KEY
goog.require()を手書きしていいのは小学生まで
PDF
Scala is-unscared
PPTX
oFの話題が殆ど出ない oF jp Summer Workout
PDF
Frank-afcproxy
PDF
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう
PDF
【関東GPGPU勉強会#2】OpenCVのOpenCL実装oclMat
Objc lambda
20130824 Lightweight Language "Go" @LL matsuri
20140822 Swift 勉強会 vol.3 - はぢめての Swift
マルチコア時代の並列プログラミング
dm-writeboost-kernelvm
Emscriptenと不思議のダンジョン
今日から始めるGopher - スタートGo #0 @GDG名古屋
What's Cooking In Ruby 2.7
すごい constexpr たのしくレイトレ!
オープン・ソースで構築するARMマイコン開発環境 ―― GCC,Eclipse,OpenOCDで統合開発環境,JTAGデバッグもできる!
Net fringejp2016
Scala conf2013
こわくないScala
Seurity Camp Award 2016
goog.require()を手書きしていいのは小学生まで
Scala is-unscared
oFの話題が殆ど出ない oF jp Summer Workout
Frank-afcproxy
【関東GPGPU勉強会#3】OpenCVの新機能 UMatを先取りしよう
【関東GPGPU勉強会#2】OpenCVのOpenCL実装oclMat
Ad

More from Akihiko Matuura (6)

PPTX
最新C++事情 C++14-C++20 (2018年10月)
PDF
アーキテクチャパターンの紹介
PPTX
Go 言語を語ってみるか
PDF
boost and c++11
PDF
C++ Template Meta Programming の紹介@社内勉強会
KEY
Open Business Model
最新C++事情 C++14-C++20 (2018年10月)
アーキテクチャパターンの紹介
Go 言語を語ってみるか
boost and c++11
C++ Template Meta Programming の紹介@社内勉強会
Open Business Model

Objectie-C de ラムダ