Month of 5月, 2009

NSPredicateの正規表現

NSPredicateでは正規表現もサポートしていて単にマッチングだけを目的とするのであれば、RegexKiOgreKitを導入する必要はありません。例えばURLマッチングであれば、

NSPredicate* reg = [NSPredicate predicateWithFormat:
  @"SELF MATCHES 'https?://[a-zA-Z0-9/.?_+~=%:;!#-]+'"];
if ([reg evaluateWithObject:source])
  {
     :
   }

Cocoaのメモリ管理関する3つのルール

in

Obujective-C 2.0の時代にアレなんですが、オブジェクトのretain/releaseに関しては時々混乱することがあるので「Learn Objective-C on the Mac」に載っていたCocoaのメモリ管理関する3つのルールをメモ。メカニズムを正しく理解するのも大切だけれど実際コードを書くときにスッっとでてくるガイドラインも大切ということで...

  1. オブジェクトをnew、alloc、copyで生成した場合、release/autoreleseメッセージを送信してオブジェクト解放の責任を負う。
  2. new、alloc、copy以外の方法でオブジェクトを取得した場合オブジェクトはautorelese対象であり、オブジェクト解放のために特になにかする必要はない。(ただし、ルール3には従う必要がある)
  3. もし、オブジェクトにretainメッセージを送信した場合、このretainに対応するrelese/autoreleseメッセージを送信する責任がある。

単純でわかりやすい。普段は1.を気をつけていればいいってことになります。僕が迷うのはアクセッサメソッドの実装で、オブジェクトの生成が離れた箇所に実装されているので迷います。本書にも載っていた、

setSomething:(id)someObject
{
  [someObject retain];
  [myObject release];
  myObject = someObject;
}

とするパタンと、

setSomething:(id)someObject
{
  [myObject release];
  myObject = [someObject copy];
}

のパタンで「アレ? retainするんだっけ?」みたいなヘモい混乱。上の例ならルール3、下の例ならルール1で(たぶん)もう迷わない(と思う)。

ホントにこれでいいのか疑問なコード

in

CEditBoxの幅を入力可能な文字数にあわせるとか、エディットボックス自体を右揃えにするなんてことは誰でも考えることだろうけど、皆どう実装しているんだろうか?僕は、

// Create Controll Font
m_ctrl_font.CreatePointFontIndirect(&logfont,pDC);
// Label A
tmpstr      = "LABEL A";
GetTextExtentPoint32(pDC->m_hDC,tmpstr.c_str(),tmpstr.length(),&textSize);
rect.top    = 20;
rect.left   = 20;
rect.bottom = rect.top  + (tm.tmExternalLeading + tm.tmHeight);
rect.right  = rect.left + textSize.cx;
CStatic* l = new CStatic;
l->Create(tmpstr.c_str(),SS_LEFT|WS_VISIBLE|WS_CHILD,rect,this);
l->SetFont(&m_ctrl_font);
// Edit A
int edge_w = GetSystemMetrics(SM_CXEDGE);
GetTextExtentPoint32(pDC->m_hDC,_T("1234567890"),10,&textSize);
rect.left   = rect.right + tm.tmMaxCharWidth;
edit_a_right = rect.right  = rect.left  + textSize.cx + (edge_w * 2);
CEdit* e = new CEdit;
e->CreateEx(WS_EX_STATICEDGE,_T("EDit"),"",
  ES_LEFT|WS_CHILD|WS_VISIBLE|WS_TABSTOP,rect,this,WM_USER+1);
e->SetFont(&m_ctrl_font);

みたいなコード(全ソース)を書いたりしていたのだけれどこれってかなり面倒。リソースエディタでペタペタ貼り付けて適当な大きさに並べておいてOnSize()あたりで幅を調整するのもありかと思うけどそれでも面倒な事は同じですよね?結局、コントロールの数だけ上記のようなコードをゴリゴリ書くわけです。