2010年5月27日木曜日

MutableDeepCopy

NSDictionaryをコピーする場合、配列がディクショナリに入っていると、単なるミュータブルコピーでは値がコピーされません。そこでディープコピーとして全ての値をコピーすることになるそうです。

そのコードが以下になります。2番目のミュータブルコピーをしているのは、ディクショナリの場合は1番目のディーブコピーをするからで、残りが配列のみになるからでしょう。ただし、現在ディープコピーをサポートしているのは、ディクショナリだけですから、ディクショナリと配列以外の型がある場合は、もう少しコーディングする必要がある、ということかもしれません。難しい...

#import "NSDictionary-MutableDeepCopy.h"


@implementation NSDictionary(MutableDeepCopy)
-(NSMutableDictionary *)mutableDeepCopy
{
    NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[self count]];
    NSArray *keys = [self allKeys];
    for (id key in keys)
    {
        id oneValue = [self valueForKey:key];
        id oneCopy = nil;
        
        if ([oneValue respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [oneValue mutableDeepCopy];
        else if ([oneValue respondsToSelector:@selector(mutableCopy)])
            oneCopy = [oneValue mutableCopy];
        if (oneCopy == nil)
            oneCopy = [oneValue copy];
        [ret setValue:oneCopy forKey:key];
    }
    return ret;
}

@end

2010年5月26日水曜日

NSMutableDictionary


変更可能なディクショナリを生成し初期化する


変更可能なディクショナリへのエントリを追加する


変更可能なディクショナリからエントリを削除する

カテゴリ

カテゴリを使用すると、サブクラス化を行わずにメソッドを既存のクラス(自分がソースを持っていないクラス)に追加できます。
カテゴリを使用すれば、自身のクラスの実装を複数のファイル間で分けることもできます。

ex.

ヘッダファイル:
#import"ClassName.h"
@interfaceClassName(CategoryName) // メソッド宣言
@end

実装ファイル:
#import"ClassName+CategoryName.h"
@implementationClassName(CategoryName) // メソッド定義
追加メソッド
@end

2010年5月22日土曜日

NSObject

NSObject

クラスを初期化する


オブジェクトを生成し、コピーし、再割当する


クラスを特定する


クラスの機能をテストする


プロトコルの適合性をテストする


メソッドに関する情報を入手する


オブジェクトの種類を標記する


メッセージを送付する


メッセージを他オブジェクトに送る


メソッドをダイナミックに解決する


エラーを取り扱う


アーカイブする


NSObject Protocol

クラスを識別する


オブジェクトを識別し、比較する


参照カウンターを管理する


オブジェクトの継承、振る舞いと適合性をテストする

  • (BOOL)isKindOfClass:(Class)aClass  required method
  •       レシーバが与えられたクラスのインスタンスかまたはそのクラスから継承されたクラスなの場合YES、それ以外はNO。
  • – isMemberOfClass:  required method
  • (BOOL)respondsToSelector:(SEL)aSelector  required method
  •       レシーバが実装または継承したメソッドが指定されたメッセージを返せるかどうかをYES,NOで返す。
  •   ex.
  •         if ([oneValue respondsToSelector:@selector(mutableDeepCopy)]
  •        oneCopy = [oneValue mutableDeepCopy];

オブジェクトを記述する


メッセージを送る


割り当て領域の決定


プロキシーの識別

メソッドが検索できない・・・・

iPhone開発のデータベースにしようと、一所懸命作成してきましたが、なんとメソッド名をフルで入れると検索できない場合があることが判明しました。なんだろう....loadだけなら検索できたりするけど....

Objective-Cにおける高速列挙

if分に見慣れない構文
   if ( (id)oneObject in nib)
があったので、調べてみると、高速列挙という構文のようです。

高速列挙に関する解説は以下にあります。

CoCoaの素、Objective-Cを知ろう
(第5回 配列とループ処理を理解しよう)
http://www.atmarkit.co.jp/fcoding/articles/objc/05/objc05a.html


Objective-Cでは、C言語のいわゆる通常のforループのほかに、よりオブジェクティブに集合のループ処理を表現するために「列挙子(NSEnumerator)」という仕組みが用意されているそうです。

これを使った場合はコードがやや複雑となるため、高速列挙ということで、for文の構造として表記可能としたようです。

対象となるオブジェクトは、NSArray, NSDictionary,NSSet,NSHashTable, NSMapTable等のNSFastEnumerationプロトコルに準拠するオブジェクトだそうです。

ちなみに、高速列挙ではオブジェクトの変更はできず、変更すると例外が発生するそうです。



構文は次のように定義されています。

for ( Type newVariable in expression ) { stmts }
または
Type existingItem;
for ( existingItem in expression ) { stmts }




以下Appleの解説です。


Objective-C には、コレクションの内容を列挙できる言語機能が提供されています。構文は次のように定義されています。

for ( Type newVariable in expression ) { stmts }
または
Type existingItem;
for ( existingItem in expression ) { stmts }

どちらの場合も、expressionNSFastEnumerationプロトコルに準拠したオブジェクト、すなわち通常は配列または列挙子を生成します(CocoaコレクションクラスのNSArrayNSDictionaryNSSetはこのプロトコルを採用し、NSEnumeratorも同様に採用しています)。

他のオブジェクトのコレクションにアクセスできるインスタンスを持つクラスはすべて、NSFastEnumerationプロトコルを採用できます(NSFastEnumerationプロトコルの実装を参照)。

NSArrayNSSetの場合は、列挙は自身の内容が対象であることは明白です。

それ以外のクラスは、反復処理の対象のプロパティを明確にする必要があります。たとえばNSDictionary、およびCore DataクラスのNSManagedObjectModelは高速列挙に対応しており、NSDictionaryはそのキーを、NSManagedObjectModelはそのエンティティを列挙します。

高速列挙を使用する利点は次のようにいくつかあります。

NSEnumeratorを直接使うなどの手法よりもはるかに効率がよい。
構文が簡単である。
「安全」である。列挙子には変更防止の機能があるため、列挙中にコレクションを変更しようとすると例外が発生します。
反復中のオブジェクトの変更が禁止されているため、複数の列挙を同時に実行できます。

2010年5月20日木曜日

2Dグラフィクス関数


Creating a Dictionary Representation From a Geometric Primitive


Creating a Geometric Primitive From a Dictionary Representation


Creating a Geometric Primitive From Values

  • CGPointMake
  • CGRectMake(x, y, width, height)
  •  指定した座標と寸法の値を代入したCGRect構造体を返す。値の型はCGFloat。x,yはMacと異なり左上の座標となる。
  • CGSizeMake

Modifying Rectangles


Comparing Values


Checking for Membership


Getting Min, Mid, and Max Values


Getting Height and Width


Checking Rectangle Characteristics