Tag Archives: Objective-C

IBOutlet接続オブジェクトの初期化

0
Filed under iOS SDK, Objective-C
Tagged as ,

難解なイントロ

説明が難しいのですが、Xcode4のリソースエディタ(旧Interface Builder)で配置したオブジェクトをまとめたUIViewを、オリジナルUIViewの派生クラスインスタンスとして設定した場合、その初期化について、どういうメソッドがどういうタイミングで呼ばれるのか分からなかったので調べてみることにしました。
うーん、分かりにくいですね。
簡単な説明にトライしてみます!

分かりやすいイントロ

リソースはほとんどプログラムでも生成できるのですが、やっぱりリソースエディタで配置したほうがやりやすいものとかあります。
そういうものをまとめたUIViewについて、たとえばButtonsとかいう独自クラスをつくってみたりすることがあります。

1
2
3
4
5
6
@interface Buttons : UIView{
  IBOutlet UILabel*  label;
  IBOutlet UIButton* bt1;
  IBOutlet UIButton* bt2;
  IBOutlet UIButton* bt3;
}

で、それをリソースエディタで配置したリソースに接続したとします。

1
2
3
@interface ButtonsContainer : UIView{
  IBOutlet Buttons* buttons;
}

で、Buttonsのクラスの初期化をしたい場合、どこのメソッドで描くべきなのか?ということなのです。

初期化の流れ

いきなり結論ですが、初期化メソッドは、
- (id) initWithCoder:(NSCoder*)aDecoder;
が、呼ばれ、その後に、
- (void)awakeFromNib;
が呼ばれます。
ちなみに、setFrameも呼ばれるので、そこに挿し込むのもいいかもしれません。
initメソッドや、initWithFrameは呼ばれないので注意が必要です。

初期化関連メソッドの呼ばれる順番

initWithCoderは次のような実装になると思います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@implementation Buttons
 
- (id) initWithCoder:(NSCoder*)aDecoder{
  if( (self=[super initWithCoder:aDecoder]) ){
    // 初期化.
    NSLog(@"2");
  }
  return self;
}
 
- (void)setFrame:(CGRect)frame{
  [super setFrame:frame];
  NSLog(@"1");
}
 
- (void)awakeFromNib{
  NSLog(@"3");
}
 
@end

setFrameは、[super initWithCoder:]から呼ばれるので最初に呼ばれるのです。
基本的な初期化が終わったら、awakeFromNibが呼ばれる、という順番ですね。
上記コードに挿入してあるNSLogはその数字を順番に出力するはずです。

考察

initではなく、initWithFrameでもなく、initWithCoderが呼ばれるので、シリアライズされているリソースがデシリアライズされていることが分かります。
今まで、(Interface Builderなどの)リソースエディタで作られたリソースをどうやって保持しているか疑問だったのですが、これでいろいろ解決しました。
ちなみに、awakeFromNibは、NSObjectにカテゴリで追加されている機能なので、普通にリファレンスを見ていても出てきません。


[AD]

↓エンジニア的読み物として今一番読みたい一冊。

エンジニアとしての生き方  IT技術者たちよ、世界へ出よう! (インプレス選書)

著者/訳者:中島 聡

出版社:インプレスジャパン( 2011-03-11 )

定価:¥ 1,680

Amazon価格:¥ 1,680

単行本(ソフトカバー) ( 272 ページ )

ISBN-10 : 4844329944

ISBN-13 : 9784844329947


↓これは良書の予感!アルゴリズムをリファレンスとしてまとめるというのがいい!

アルゴリズムクイックリファレンス

著者/訳者:George T. Heineman Gary Pollice Stanley Selkow

出版社:オライリージャパン( 2010-04-26 )

定価:¥ 3,360

Amazon価格:¥ 3,360

単行本(ソフトカバー) ( 396 ページ )

ISBN-10 : 4873114284

ISBN-13 : 9784873114286


↓上記アルゴリズムクイックリファレンスを見て連想したのはこの名著。もちろん私も持っていますし、プログラマは必携です!

C言語による最新アルゴリズム事典 (ソフトウェアテクノロジー)

著者/訳者:奥村 晴彦

出版社:技術評論社( 1991-03 )

定価:¥ 2,447

Amazon価格:¥ 2,447

単行本 ( 443 ページ )

ISBN-10 : 4874084141

ISBN-13 : 9784874084144


↓iPad2を使い始めているのですが、こういうスタンドは欲しくなりますね!机の上に置いておくより絶対良さそう。しかもこれはスタンド自身が収納性に優れている!

デバイスジャパン Apple iPad対応スタンド(Xstand)

デバイスジャパン Apple iPad対応スタンド(Xstand)

定価:¥ 3,980

Amazon価格:¥ 1,100

カテゴリ:エレクトロニクス


↓iPad2に手で書いていると段々限界が見えてくる。やっぱりペンが欲しい!

プリンストンテクノロジー iPad/iPhone/iPod touch専用タッチペン (ブラック) PIP-TP2B

プリンストンテクノロジー iPad/iPhone/iPod touch専用タッチペン (ブラック) PIP-TP2B

定価:¥ 1,580

Amazon価格:¥ 798

カテゴリ:エレクトロニクス

発売日:2010-07-10


lipo:複数アーキテクチャ向けライブラリを結合するコマンド

0
Filed under iPhoneアプリ, トラブルシューティング, プログラミング言語, 仕事ツール
Tagged as , , , , ,

Odd merge signphoto © 2008 Jason McHuff | more info (via: Wylio)

iOS Static Libraries

iOS Static LibrariesというiOSアプリ向けにビルドされた便利ライブラリ群があります。
ちょっと必要なライブラリが含まれていて、自分でビルドするよりも便利ですし、iOS SDKがバージョンアップされたらきちんと更新されているので便利に使わせてもらっています。
先日、iOS Static Librariesの、iOS SDK 4.3向けのビルドがリリースされました。
しかし、これがちょっと曲者で、現在iOSデバイスはARM V6かARM V7の二つがあり、今回のビルドバーションは、ARMアーキテクチャ向けに二つのビルドがなされているのです。
ARM V6というのはiPhone 3G以前で使われていたものなので、対応機種を3GS以降に絞るならARM V7のみに対応したビルドを行えばいいのですが、まだ3Gも無視できない状況ですので、これをなんとかしないといけません。
そして、Xcodeのビルド設定的には一つにマージされている方が便利なのです。
マージって、、なんかツールがあるのか?設定でどうにか回避できるものなのか?と調べてみたところ、偶然、lipoというコマンドを知ることが出来ました。

lipoコマンド

man lipoによると、次のような説明があります。

The lipo command creates or operates on “universal” (multi-architecture) files.

まさに複数アーキテクチャ対応のユニバーサルファイルを生成するためのツールだと分かります。
そして、これはiOSアプリを開発できる環境ならインストール済みであることも分かりました。
例として、前述したiOS Static Librariesについて調べてみます。
ARM V6用のライブラリ libcurl.a について下記のコマンドで調べてみます。すると、ちゃんとターゲットアーキテクチャを調べることが出来ることが分かります。

1
2
3
$ lipo -info libcurl.a
input file libcurl.a is not a fat file
Non-fat file: libcurl.a is architecture: armv6

そして、ユニバーサルファイルを作る例ですが、例えば、ARM V6用、V7用のlibcurl.aが、./armv6/libcurl.a と、 ./armv7/libcurl.a にある場合には、次のようにして生成できます。出力先は ./fat/ とします。

1
lipo -arch armv6 ./armv6/libcurl.a -arch armv7 ./armv7/libcurl.a -create -output ./fat/libcurl.a

直感的でわかりやすいですね!

armv6/armv7ユニバーサルライブラリをつくる

というわけで、今回の目標である「iOS Static Librariesのarmv6/armv7ユニバーサルライブラリをつくる」シェルスクリプトを載せておきます。
まず、準備として次のようなファイル配置にしておきます。

workディレクトリ直下で実行したら、work/lib以下にユニバーサルライブラリファイルが生成されると思います。また、処理対象は”*.a”ファイルのみ、とします。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/bash
 
echo 'makefat.sh -- start!'
 
RootV6='./iPhoneOS-V6-4.3'
 
for lib_armv6 in `find $RootV6 -name "*.a" -print`
do
	lib_armv7=`echo $lib_armv6 | sed "s/V6/V7/g"`
	echo $lib_armv6
	echo $lib_armv7
	lib_fat=`echo $lib_armv6 | sed "s/iPhoneOS-V6-4.3\///g"`
	echo $lib_fat
 
	lipo -arch armv6 $lib_armv6 -arch armv7 $lib_armv7 -create -output $lib_fat
done
 
echo 'makefat.sh -- end!'

one more lipo

lipoは複数アーキテクチャのユニバーサルライブラリをから特定のアーキテクチャパートを削除することも出来たりするようです。
両方対応版のライブラリのみが提供されている環境で、不要なアーキテクチャを削除すれば、ビルド後の実行ファイルサイズが小さくなったりすると思うので、そういう用途にも使えそうですね。


[AD]

↓リンカーとかプログラムをきっちりやろうとしたら外せない部分。去年出たらしいこの本、面白そうですね。

リンカ・ローダ実践開発テクニック―実行ファイルを作成するために必須の技術 (COMPUTER TECHNOLOGY)

著者/訳者:坂井 弘亮

出版社:CQ出版( 2010-08 )

定価:¥ 2,940

Amazon価格:¥ 2,940

単行本 ( 303 ページ )

ISBN-10 : 4789838072

ISBN-13 : 9784789838078


↓もうすぐ発売されるWEB+DB PRESS plusシリーズ。気になるタイトルです!!

良いコードを書く技術 -読みやすく保守しやすいプログラミング作法 (WEB+DB PRESS plus)

著者/訳者:縣 俊貴

出版社:技術評論社( 2011-04-09 )

定価:¥ 2,394

Amazon価格:¥ 2,394

単行本(ソフトカバー) ( 240 ページ )

ISBN-10 : 4774145963

ISBN-13 : 9784774145969


↓こういうのじっくり読んでみたいなぁ〜。

プログラミングコンテストチャレンジブック

著者/訳者:秋葉 拓哉 岩田 陽一 北川 宜稔

出版社:毎日コミュニケーションズ( 2010-09-11 )

定価:¥ 3,444

単行本(ソフトカバー) ( 316 ページ )

ISBN-10 : 4839931992

ISBN-13 : 9784839931995


↓結局まだ読んでいない数学ガールシリーズ最新作はアルゴリズムへ突入!

数学ガール/乱択アルゴリズム

著者/訳者:結城 浩

出版社:ソフトバンククリエイティブ( 2011-03-02 )

定価:¥ 1,995

Amazon価格:¥ 1,995

単行本 ( 480 ページ )

ISBN-10 : 479736100X

ISBN-13 : 9784797361001


NSMutableArrayのNULL初期化

0
Filed under iOS SDK, Objective-C
Tagged as , ,

ちょっとNSMutableArrayの使い方でハマったのでメモです。
box cube empty clear glassphoto © 2008 Simon | more info (via: Wylio)

やりたいこと:配列をヌルで埋めたい

  • 大量のオブジェクトを管理したい
  • その個数は決まっているので固定長で確保しておきたい
  • まずnilで埋めておき、後で任意のインデックスのオブジェクトを置き換えたい

という意図で次のようなコードを書くとエラーになります。

1
2
3
4
NSMutableArray* array = [NSMutableArray arrayWithCapacity:numMax];
for( int i=0; i<numMax; i++ ){
  [array addObject:nil];
}

次のコードも無理です。

1
2
3
4
NSMutableArray* array = [NSMutableArray arrayWithCapacity:numMax];
for( int i=0; i<numMax; i++ ){
  [array replaceObjectAtIndex:i withObject:nil];
}

これは、NSMutableArrayはnilを要素として受けつけないからです。
さぁどうしよう、と思って調べてみたらいつものQ&Aサイト:StackOverFlowにまさにそんな意図の質問がありました!

NSNull

で、解決方法は、NSNullというクラスのオブジェクトを作る、ということでした。

具体的なコードは次のようになります。

1
2
3
4
NSMutableArray* array = [NSMutableArray arrayWithCapacity:numMax];
for( int i=0; i<numMax; i++ ){
  [array addObject:[NSNull null]];
}

これならオブジェクトを配置できて、しかも後からNULL判定できます。
ちなみに判定コードは次のようになります。

1
2
3
4
NSNull* nullValue = [NSNull null];
if( [array objectAtIndex:index] == nullValue ){
  NSLog(@"This is null!!");
}

もちろん、NSNullのオブジェクトが入っているので、nilとの比較では判定できません。


[AD]

↓タイトルからは予想できないが、XML解析、OAuth認証、Core Dataを使ったサンプルなど意外に良書の予感!

つくって覚えるObjective-C入門 iOS対応

著者/訳者:オフィス加減

出版社:アスキー・メディアワークス( 2011-03-10 )

定価:¥ 1,890

Amazon価格:¥ 1,890

単行本(ソフトカバー) ( 272 ページ )

ISBN-10 : 4048703641

ISBN-13 : 9784048703642


↓こないだ買いました!Titanium、Facebookアプリなど、なかなかおもしろい話題が多く、これはお買い得!

WEB+DB PRESS Vol.61

著者/訳者:西岡 祐弥 濱田 章吾 浦嶌 啓太 高橋 健一 柴田 博志 井上 誠一郎 大谷 弘喜 荻野 淳也 原 悠 増井 俊之 横山 彰子 浜本 階生 ミック uupaa 塙 与志夫 はまちや2 大沢 和宏 中島 聡 矢野 りん 中島 拓

出版社:技術評論社( 2011-02-24 )

定価:¥ 1,554

大型本 ( 200 ページ )

ISBN-10 : 4774145440

ISBN-13 : 9784774145440


↓とうとう出た!「まんが日本昔ばなし」のDVD BOX!!第1集は、「桃太郎」「カチカチ山」など全20話

まんが日本昔ばなし DVD-BOX 第1集(5枚組)

販売元:東宝( 2011-04-01 )

定価:¥ 14,700 ( 中古価格 ¥ 8,980 より )

Amazon価格:¥ 10,940

時間:225 分

5 枚組 ( DVD )


Objective-Cの既存のクラスを拡張する仕組み

0
Filed under iPhone, Objective-C, プログラミング言語
Tagged as , , , , ,

Objective-Cには「カテゴリ」という機能があり、それについて調べたときのメモをまとめました。

その名は「カテゴリ」

ネットに転がっているソースを見ていて、それまで見たことなかった書き方があったときにはそれをどうやって調べたらいいのか、なかなか手こずります。その書き方そのものの名を知らないからです。
今回の例で言うと「カテゴリ」という機能のことで、下記のような感じで書かれていたら、それはカテゴリ機能を使っているのです。

1
@inteface NSString (HogeHoge)

このカテゴリ機能を活用すると、既存のクラスをちょっと機能拡張したい時に無駄なクラスを作る必要がなくなります。
例えば、文字列を扱うクラス NSString をに機能を追加したいことはよくあるのですが、NSStringの中身に応じたハッシュ値(MD5)を出力できるようなメソッドを追加する、という例に説明してみます。
MD5の機能実装の参考にしたのはこちらのサイト。関数の中身は全く同じです。

ざっくりしたカテゴリの書き方と使い方

まず、カテゴリ定義の書き方。
NSStringにMD5の機能を追加する場合、ファイル名は、NSString+MD5.h, NSString+MD5.m とするのがマナーのようです。
また、後述するソースを見ると分かるのですが、定義部は @inteface NSString (MD5)、実装部は @implementation NSString (MD5) という感じにして、あとは通常のクラス定義と同じように書きます。
次に使い方ですが、#import “NSString+MD5.h” として一緒にビルドすれば、そのソース内でNSStringインスタンスは全てMD5カテゴリの機能を持つことが出来ますので、下記のようなコードでMD5値を出力させることが出来ます。

1
2
NSString* strTest = @"テスト文字列";
NSLog( @"original[%@], MD5[%@]", strTest, [strTest MD5String] );

NSString+MD5 コード全容

1
2
3
4
5
6
7
//  NSString+MD5.h
 
#import <Foundation/Foundation.h>
 
@interface NSString (MD5)
- (NSString*) MD5String;
@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//  NSString+MD5.m
 
#import "NSString+MD5.h"
#import <CommonCrypto/CommonDigest.h> // for CC_MD5
 
@implementation NSString (MD5)
- (NSString *) MD5String
{
  const char *cStr = [self UTF8String];
  unsigned char result[CC_MD5_DIGEST_LENGTH];
  CC_MD5( cStr, strlen(cStr), result );
  return [NSString stringWithFormat:
    @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
    result[0], result[1], result[2], result[3], 
    result[4], result[5], result[6], result[7],
    result[8], result[9], result[10], result[11],
    result[12], result[13], result[14], result[15]
    ];  
}
@end

iOS SDKのMD5関数についての説明

おまけとして、上記のソースの内容を説明します。
MD5への変換関数 CC_MD5はiOS SDKにC言語ライブラリが用意されています。(リファレンスはこちら

CC_MD5は、次のように定義されています。

1
2
extern unsigned char*
CC_MD5(const void *data, CC_LONG len, unsigned char *md);

data が元になるデータのポインタ。
len がdataの長さ。
md がMD5計算の結果を格納する出力用バッファへのポインタで、CC_MD5_DIGEST_LENGTHの長さが必要なので、予め用意しておきます。本当はCC_MD5_DIGEST_LENGTHの長さに合わせて、出力部分を対応できるよう書いておく必要がありますが、CC_MD5_DIGEST_LENGTHは、そうそう16から変わることはないので、出力部分を固定で16要素並べてstringWithFormatで出力させています。

クラスの機能分割、という視点

カテゴリについての詳しい説明は、「Dynamic Objective-C」という書籍にも3ページに渡って説明されているのですが、こちらでの視点はチョット違う。

Dynamic Objective-C

著者/訳者:木下 誠

出版社:ビー・エヌ・エヌ新社( 2009-03-27 )

定価:¥ 3,360

Amazon価格:¥ 3,360

単行本 ( 456 ページ )

ISBN-10 : 4861006414

ISBN-13 : 9784861006418


そのセクション名は「カテゴリ ―動的なメソッドの追加によるクラスの拡張」となっていながらも、最初の段落の説明は次にように書かれている。

Objective-Cには、カテゴリと呼ばれる機能がある。クラスが持つメソッドを、名前の通りカテゴリごとに分類するための機能だ。これを使うことで、大きなクラスでもコーディングしやすいように分割することができる。

そもそもカテゴリとは、クラス実装を分割するための仕組み、だというのだ。
なるほど、そう考えるとカテゴリが「カテゴリ」という名前の由来もわかるし、ウェブに転がるサンプルのファイル名がHOGEHOGE-FOO.hとかハイフン繋ぎになっているモノがあるのも理解できる。
MVCモデルでクラスを分けても大きくなってしまうクラスはあるし、その場合にはカテゴリを使った機能分割も視野に入れていいかもしれない。
その他にもObjective-Cの深いところをじっくり説明してくれている「Dynamic Objective-C」はおすすめ書籍です!

カテゴリで出来ないこと

後から知ったのですが、カテゴリ機能で「クラスのインスタンス変数の追加」は出来ないようですね。
これ、結構重要なポイントだと思います。

参考サイト:『kuro’s blog : Objective-C:カテゴリで「できること」と「できないこと」』


[AD]

↓「CHAPTER09 カテゴリ」とカテゴリについて章を割いて説明されているようです!

詳解 Objective-C 2.0 改訂版

著者/訳者:荻原 剛志

出版社:ソフトバンククリエイティブ( 2010-12-17 )

定価:¥ 3,990

Amazon価格:¥ 3,990

大型本 ( 608 ページ )

ISBN-10 : 4797361786

ISBN-13 : 9784797361780


↓昨年8月に亡くなった今敏が1985年〜1986年に連載していたマンガ!面白そう!

OPUS(オーパス)上(リュウコミックス) [コミック]

著者/訳者:今 敏

出版社:徳間書店( 2010-12-13 )

定価:¥ 980

Amazon価格:¥ 980

コミック ( ページ )

ISBN-10 : 4199502211

ISBN-13 : 9784199502217


↓PS3もXbox360も持っていないけど、これは面白そう!

キャサリン 特典 サントラCD付き

キャサリン 特典 サントラCD付き

定価:¥ 7,329

Amazon価格:¥ 4,860

カテゴリ:Video Game

発売日:2011-02-17