objcでinitの呼び出しを抑制する

カプセル化の破壊を抑える為setterは出来る限り使わず、
以下の指定イニシャライザの利用を推奨させたい時(initを呼べない様にしたい)

- (id)initWithName:(NSString *)inName age:(NSInteger)inAge



ヘッダにclang language extentionsを書けば[[Foo alloc] init];の呼び出し時にコンパイルエラーにできる。

- (id)init __attribute__((unavailable("init is not available")));



強引に呼ばれてしまった場合は

Foo *foo = [[Foo alloc] performSelector:@selector(init:)];



NSAssertやraise:format等で例外を発生させinitを使わせなければよい。

- (id)init
{
    [NSException raise:NSGenericException
                format:@"Disabled. Use +[[%@ alloc] %@] instead",
     NSStringFromClass([self class]),
     NSStringFromSelector(@selector(initWithName:age:))];
    return nil;
}

[参考]
stackoverflow Is it possible to make the -init method private in Objective-C?

objcの関連参照でUIViewにプロパティを追加してみる。

objectivecの関連参照を試したのでメモ。
UIView拡張で試したサンプル(github)


objcのカテゴリではインスタンス変数の追加はできない。
関連参照をつかえば疑似的に変数を追加できる。


必要な手順。
1. objc/runtime.hのインポート

#import



2. 追加する変数を保持する為のキーの準備 (voidポインタならOK)

// キーの一例
static char showRectKey; // 表示フレーム用のキー
static char hideRectKey; // 非表示フレーム用のキー



3. 関連オブジェクトの設定/クリア
objc_setAssociatedObject関数で設定する。
objectは参照を追加する対象、keyはキー、valueは追加するオブジェクト、policyはretainとか。
関連を解消する時はvaluenilをセットする。

void objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy)



関連オブジェクトの設定例

// 表示フレームの保持
- (void)setShowFrame:(CGRect)inFrame
{
    NSValue *value = [NSValue valueWithCGRect:inFrame];
    objc_setAssociatedObject(self, &showRectKey,
                             value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}



[参考]
UIView拡張で試したサンプル(github)
Objective-Cプログラミング言語_関連参照
詳解Objective-C 2.0 第3版 (アフリエイトリンクです。)

RestKitを使う上の参考情報メモ

RestKitを使う上の参考情報メモ

・ちょっと使うにはNImbusKit等と一緒でボリューミーな印象
・更新頻度が高いので期待 https://github.com/RestKit/RestKit/graphs
・MagicalRecordsと一緒に使っているサンプル https://github.com/blakewatters/RKMagicalRecord

■本家 RestKit公式/github/googleGroup/最近更新があったっぽいページ等
http://restkit.org/
https://github.com/RestKit/RestKit/
https://groups.google.com/forum/?fromgroups#!forum/restkit
https://github.com/RestKit/RestKit/wiki/Installing-RestKit-v0.20.x-as-a-Git-Submodule


■日本語の情報 (古いのも多いので注意する)
RestKitの紹介スライド
http://www.slideshare.net/hedjirog/rest-kit

RestKitでRSSフィードを取得してモデルとマッピングしてみる
http://blog.yabasoft.biz/archives/2867

RestKit 0.10.2 送信中のリクエストをキャンセルする
http://qiita.com/items/3744049729124acf26e8

RestKit.hがみつからないよっておこられる場合の処方箋
http://blog.ishitoya.info/entry/20120419/1334819271

objective-cで確保したメモリサイズを調べる

objective-cで確保するメモリサイズについてのメモ


sizeof演算子で変数型のサイズを表示できる。
以下はその例

// (c99ではzuでsize_t型を出力可能)
printf("sizeof(short int)  = %zu\n", (size_t)sizeof(short int));



sizeofの戻り値size_tは実装によってサイズが異なる。
size_tは__darwin_size_tのtypedefとして定義されている。
以下はMacOSX10.8.sdk/usr/include/sys/types.h内の定義

typedef __darwin_size_t		size_t;



__darwin_size_tは__SIZE_TYPE__が未定義の場合unsigned longとなっている。

#if defined(__GNUC__) && defined(__SIZE_TYPE__)
typedef __SIZE_TYPE__		__darwin_size_t;	/* sizeof() */
#else
typedef unsigned long		__darwin_size_t;	/* sizeof() */
#endif



size_tのサイズを表示するには以下の様にする。

        // sizeofの戻り値型のsize_t自体のサイズを表示
        size_t t;
        printf("sizeof(size_t)  = %zu\n", (size_t)sizeof(t));
        // 結果 sizeof(size_t)  = 8



Objective-cのオブジェクトはポインタのサイズを返すので注意
64bitなら8byteを返す。以下はその確認例

        NSString *myStr = @"test";
        printf("sizeof(NSString)  = %zu\n", (size_t)sizeof(myStr));
        // 結果 sizeof(NSString)  = 8



実行時に確保したメモリサイズを知るには、malloc_size関数を使う
実際のメモリより大きいサイズを返す場合があるとの事
注意:#import をインポートしておく必要がある。
参考:http://www.unix.com/man-page/OSX/3/malloc_size/
以下は例

        NSArray *array = @[@"test1",@"test2",@"test3"];
        NSLog(@"size of array: %zu", malloc_size((__bridge const void *)(array)));
        // 結果(略) size of array: 48

        //又は、<objc/objc-runtime.h>のインポートで以下も可能
        NSLog(@"size of myObj instanceSize: %zu", class_getInstanceSize([MyObj class]));



初期化時に各インスタンス変数が確保するメモリも知るには?
以下参考でallocを実行時に置換し、より正確なサイズを確認している。
iPhone開発でメモリ使用量を把握しよう! 1
iPhone開発でメモリ使用量を把握しよう! 2


要素100のint配列を生成する際にmallocとfreeではダメなのかという議論
http://stackoverflow.com/questions/1150650/is-it-ok-to-use-classic-malloc-free-in-objective-c-iphone-apps


もう少しちゃんと読みたい
Objective-C Runtime Reference


64bit環境でのmallocで確保するサイズの違い、
1024byteまでは16byteで、1024を超えると512byteで丸められる等の解説がある。
64-Bit Transition Guide for Cocoa

NSNumberを要素に持つNSArrayを使う際のメモ。

NSNumberを要素に持つNSArrayを使う際のメモ。
最頻出要素はNSCountedSetを利用。
参考:
最頻出要素の取得(stackoverflow)
キー値コーディングプログラミングガイド

    // NSNumber配列を初期化
    NSArray *numbers = @[@9,@4,@5,@1,@1,@17,@9,@6,@9];
    
    // 昇順ソート
    NSArray *asecNumbers = [numbers sortedArrayUsingSelector:@selector(compare:)];
    NSLog(@"asecNumbers = %@",asecNumbers);
    
    // 降順ソート
    NSSortDescriptor *descDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"self" ascending:NO];
    NSArray *descNumbers = [numbers sortedArrayUsingDescriptors:@[descDescriptor]];
    NSLog(@"descNumbers = %@",descNumbers);
    
    // 最大、最小、平均、合計値の取得
    NSLog(@"max of numbers = %@",[numbers valueForKeyPath:@"@max.self"]);
    NSLog(@"min of numbers = %@",[numbers valueForKeyPath:@"@min.self"]);
    NSLog(@"avg of numbers = %@",[numbers valueForKeyPath:@"@avg.self"]);
    NSLog(@"sum of numbers = %@",[numbers valueForKeyPath:@"@sum.self"]);
    
    // 重複データを取り除く
    NSArray *distinctNumbers = [numbers valueForKeyPath:@"@distinctUnionOfObjects.self"];
    NSLog(@"distinctNumbers = %@",distinctNumbers);
    
    // 6以上のデータを取得
    NSPredicate *over6Pred = [NSPredicate predicateWithFormat:@"SELF >= 6"];
    NSArray *over6Array = [numbers filteredArrayUsingPredicate:over6Pred];
    NSLog(@"over6Array = %@",over6Array);

    // 最頻出のデータを取得
    NSCountedSet *set = [NSCountedSet setWithArray:numbers];
    int highest = 0;
    NSNumber *mostFqtNumber  = @0;
    for (NSNumber *n in set) {
        if ([set countForObject:n] > highest) {
            highest = [set countForObject:n];
            mostFqtNumber = n;
        }
    }
    NSLog(@"most frequent number = %@",mostFqtNumber);

Xcode4で途中からローカルgitを追加する。

既存プロジェクトにローカルgitを追加する方法のメモ


ターミナルでxxx.xcodeprojのあるフォルダまで移動して以下コマンドを実行

git init



gitignoreファイルを作成、追加する。
参考:Xcode 4で既存のXcodeプロジェクトからローカルGitリポジトリを作成するには


git statusで追加するファイルを確認

git status



ファイル追加

git add .



ログメッセージ付きでコミット

git commit -m "Initial commit"



Xcodeは空のgitリポジトリがあると自動検出するようなので、
参考:How to Create Git Repos for Existing Xcode Projects
Xcodeを起動すればSource ControlからCommitができるようになっている。

Xcode4.6のSimulated Metricsについてメモ。

Xcode4.6における、Simulated Metricsについてメモ。

StoryBoardでViewControllerを選択して、
Attributes InspectorをみるとSimulated Metricsというのがある。

これはあくまでStoryBoard上でのレイアウトを助けるもので、実行時には無視される。
参考:http://www.raywenderlich.com/ja/25696/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AE-storyboard-in-ios-5-part-1


それぞれの意味は以下
・Inferred = 推論、NavigationController内であればNavigationBarを表示等
・None = なし
・Freeform = 画面サイズを超えてレイアウトができる(ScrollViewとかに使う)
・その他(Retinaディスプレイ等)



ただ、NavigationControllerのTopBarをNoneにすると
Shows Navigation Barのチェックも一緒に外れてしまい、
コンテンツビューのTopBarが実行時に消えてしまうので注意。