2012-01-19
XCode4.2のstd::modfがリリースビルドでなんか変
#include <iostream> #include <cmath> int main (int argc, const char * argv[]) { float x = 3.14; float integral; float fractional = std::modf(x, &integral); std::cout << x << ":" << integral << ":" << fractional << std::endl; return 0; }
デバッグ版では期待通りに動くんですけど、リリース版だとintegralの値がなんか変。std::modfの代わりに::modfを使うと問題なさげ。
XCode4.2で、UniversalではなくiPhone版とiPad版別々のバイナリを作る為のスケルトン・プロジェクトを作るメモ
注意) 細かいところ、いろいろ端折っているので補間作業が必要です
適当なテンプレートを選択し、Device Familyを「Universal」でプロジェクトをつくる
Summary
Targetを右クリックしてDuplicateする
"MYAPP copy"というTargetが出来る。
Targetの名前を変更する
"MYAPP"→"MYAPP iPhone"
"MYAPP copy"→"MYAPP iPad"
Deviceを変更
Universal->iPhone
Universal->iPad
Build Settings
Product Nameを適当に変更
iPhone版とiPad版を区別できるように適当なマクロを設定
Preprocessor MacrosにIPAD_VERSIONとか適当なマクロを設定
Build Phases
Copy Bundle Resourcesについて、対象デバイスそれぞれについて必要なリソースのみ追加(いらんものを削除)する。
デュプッたplistのファイル名と保存場所変更
plistのファイル名と保存場所を変更して、Build SettingsのInfo.plist Fileを変えればOK(指定するパスは*.xcodeprojから見たもの)
スキーム名の変更
MYAPP copyとなっているのでManage Schemes...で「MYAPP for iPhone」「MYAPP for iPad」等に変更する
AppDelegate.mのコード編集
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // Override point for customization after application launch. if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { self.viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController_iPhone" bundle:nil] autorelease]; } else { self.viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController_iPad" bundle:nil] autorelease]; } self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; }
このコードを下記のように自分で定義したマクロを使って、XIBファイルを読み別ける。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; #ifdef IPAD_VERSION self.viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController_iPad" bundle:nil] autorelease]; #else self.viewController = [[[MyViewController alloc] initWithNibName:@"MyViewController_iPhone" bundle:nil] autorelease]; #endif self.window.rootViewController = self.viewController; [self.window makeKeyAndVisible]; return YES; }
以後の作業
以後はファイルを追加する時、「Add to targets」で対象となるデバイスにだけ追加するとか、「Build Phasese」の「Compile Sources」「Copy Bundle Resources」で個々のデバイスに必要なファイルを管理する必要がある。
2011-11-29
std::set::iteratorはconst
以下のコードはXCode4.2でコンパイルできない。
#include <iostream> #include <set> class Hoge { public: Hoge(int value) : value_(value), optionValue_(0) {} int value() const { return value_; } void setValue(int value) { value_ = value; } int optionValue() const { return optionValue_; } void setOptionValue(int opt) { optionValue_ = opt; } private: int value_; int optionValue_; // ソートには関係のないメンバ変数 }; bool operator<(const Hoge& a, const Hoge& b) { return a.value() < b.value(); } int main (int argc, const char * argv[]) { std::set<Hoge> hogeSet; hogeSet.insert(Hoge(1)); hogeSet.insert(Hoge(2)); hogeSet.insert(Hoge(3)); hogeSet.insert(Hoge(5)); for ( std::set<Hoge>::iterator it = hogeSet.begin(); it != hogeSet.end(); ++it ) { it->setOptionValue(1); // <= ココでエラー std::cout << it->value() << std::endl; } return 0; }
XCodeのSTLは以下のようにstd::set::iteratorがconst_iteratorと同様のものとして定義されているからのようだ。
typedef typename _Rep_type::const_iterator iterator;
typedef typename _Rep_type::const_iterator const_iterator;
どうやら、std::setはソートされたコンテナだから、iterator経由でごにょごにょやられたらiteratoソート状態が保たれなくなってしまうからのようだ。
ここでのoptionValue_はソートに関係しないメンバなので、気持ち悪いがmutableを使って以下のように回避した。
#include <iostream> #include <set> class Hoge { public: Hoge(int value) : value_(value), optionValue_(0) {} int value() const { return value_; } void setValue(int value) { value_ = value; } int optionValue() const { return optionValue_; } void setOptionValue(int opt) const { optionValue_ = opt; } private: int value_; mutable int optionValue_; // ソートには関係のないメンバ変数 }; bool operator<(const Hoge& a, const Hoge& b) { return a.value() < b.value(); } int main (int argc, const char * argv[]) { std::set<Hoge> hogeSet; hogeSet.insert(Hoge(1)); hogeSet.insert(Hoge(2)); hogeSet.insert(Hoge(3)); hogeSet.insert(Hoge(5)); for ( std::set<Hoge>::iterator it = hogeSet.begin(); it != hogeSet.end(); ++it ) { it->setOptionValue(1); std::cout << it->value() << std::endl; } return 0; }
2011-09-22
XCode4(gcc4.2)でtypenameがないと叱られる
template <typename T> class Foo { public: Foo(T v) : v_(v) {} private: T v_; }; template <typename T> void bar(T v) { std::list<Foo<T> >::iterator it; // NG }
このコードは、
std::list<Foo<T> >::iterator it;
でエラーになる。
「std::list<Foo<T> >::iterator」の前に「typename」を加えればOK。
template <typename T> class Foo { public: Foo(T v) : v_(v) {} private: T v_; }; template <typename T> void bar(T v) { typename std::list<Foo<T> >::iterator it; // OK }
2010-12-08
iOS4.2で数字キーボードを開こうとするとクラッシュ
iOS4.2.1で、数字キーボードを指定したUITextFieldでキーボードを開こうとすると、UIKeyboardLayoutRoman setLabelでクラッシュすることがある。
becomeFirstResponderをやっていたので、setUserInteractionEnabled問題かと思ったが、becomeFirstResponderせず、UITextFieldをタップしiOSが自ら数字キーボードを開こうとしてもクラッシュ。
いろいろ調べた結果、どうやら、直前に日本語キーボードを表示させた状態で、これが起こるようだ。
メモAppなどで、英語(US)キーボードにしてから、アプリを切り替えて数字キーボードを指定したUITextFieldでキーボードを開けばクラッシュしない。逆にメモAppなどで、日本語キーボードにしてから、アプリを切り替えるとクラッシュする。
UITextFieldにキーボードタイプをを指定しなければ問題は起こらない。
しばらくは、数字キーボードを指定するのはよそう・・・
2010-05-07
Audio MIDI設定.appで、複合デバイス設定がおかしくなった時の対処方法メモ
http://support.apple.com/kb/HT3956?viewlocale=ja_JP
これを試そうとして、いろいろいじっていたら、設定の変更も、消すことも出来ない複合デバイスが出来てしまった。
以下のファイルを消し、Audio MIDI設定.appを再起動するだけで、元に戻った。
/Library/Preferences/com.apple.audio.AggregateDevices.plist
2010-03-16
メモ - std::vectorにおいてN番目の要素を削除する
// delete the Nth element (Index starts with 0) in std::vector.
std::vector<HOGE>::iterator it = theVector.erase(theVector.begin() + N);











