Hatena::ブログ(Diary)

ブロードバンド対応日記

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」でプロジェクトをつくる

f:id:matobow:20120119131435p:image:w360

Summary

Targetを右クリックしてDuplicateする

"MYAPP copy"というTargetが出来る。

f:id:matobow:20120119132004p:image:w360

Targetの名前を変更する

"MYAPP"→"MYAPP iPhone"

"MYAPP copy"→"MYAPP iPad"

f:id:matobow:20120119132133p:image:w360

Deviceを変更

Universal->iPhone

Universal->iPad

f:id:matobow:20120119132556p:image:w360

Build Settings

Product Nameを適当に変更

f:id:matobow:20120119132802p:image:w360

iPhone版とiPad版を区別できるように適当なマクロを設定

Preprocessor MacrosにIPAD_VERSIONとか適当なマクロを設定

f:id:matobow:20120119132930p:image:w360

Build Phases

Copy Bundle Resourcesについて、対象デバイスそれぞれについて必要なリソースのみ追加(いらんものを削除)する。

f:id:matobow:20120119133526p:image:w360

デュプッた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;
}

XCodeSTLは以下のように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

}

2011-02-25

Audio Unit Class Hierarchy

勉強のため自分なりに書き直してみた。

f:id:matobow:20110225171220p:image

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);
2005 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 |
2007 | 02 | 03 | 05 | 06 | 08 | 10 | 11 | 12 |
2008 | 03 | 05 | 06 | 09 |
2009 | 03 |
2010 | 03 | 05 | 12 |
2011 | 02 | 09 | 11 |
2012 | 01 |