UIColorの値をとる時に便利なツール Developer Color Picker
ダウンロードしたDeveloperColorPicker.colorPickerを/home/Library/ColorPickers/に入れるだけ。
他のColor picker同様、虫眼鏡ツールを使って色を取得する事もできます。
iPhoneとAndroidアプリを開発できるcoronaってのがあるらしい。
これって、AdobeがFlash CS5に搭載しようとした機能みたい? ※ActionScriptでのコンパイルは規約違反になるため断念
ActionScript、JavaScript、PHPの能力があればできるらしいが、果たして全部の機能が網羅されているのだろうか?
主要な機能をまとめて集約してライブラリにしてるみたいですね。
評価してないのでなんともいえませんが、
・言語の敷居が低い ・コーディングが格段に少なくなる ※ゲーム制作とかはOpenGL-ESに対応してるので圧倒的に有利
・Corona SDKにない機能は搭載できない ・iPhone、Androidに新しいSDKがでたら対応できない
簡易アプリやデザイナーさん向けのツールのような気もする。 一応、30日お試し版で試してみようかな?
アプリを作ってみて初めてreleaseの重要性を実感しました(^^;) CGContextでUITextField、UILabelを大量に追加したUIViewを往復してると、動作が重くなりメモリリーク(>_<)
UINavigationControllerでViewController(@synthesizeした)をpush後、親ページに戻った時(popした時)に、viewDidUnloadが発生しないことがわかりました。
その為、以下の遷移でを繰り返していると
(1) UIViewControllerをinitWithNibNameでallocし、UINavigationControllerに追加(pushViewController) (2) UIViewControllerのviewDidloadが呼ばれる (3) UIViewControllerに大量のオブジェクトをaddSubViewする (3) UINavigationControllerで戻る(popViewController) (4) UIViewControllerがdeallocされない
と、通常は2~3Mのメモリを行ったりきたりするのですが、ページにアクセスする毎に500K単位で増えていきました。
(1) pushするUIViewControllerを@synthesizeして(せざるを得なかった)利用していた (2) pushするUIViewControllerをpush後にreleaseしていなかった(できなかった) (3) UIViewにaddSubViewしたオブジェクトをreleaseしていなかった
pushするUIViewControllerを@synthesizeしていた(せざるを得なかった)のは、自分の設計ミス(^^;)
@synthesize hogeViewController;
...
-(void)pageHoge {
hogeViewController= [[HogeViewController alloc] initWithNibName="HogeViewController" bundle:nil];
[self.navigationController pushViewController:hogeViewController animated:YES];
}
他のメソッドでViewControllerを利用したいばかりに、不用意に@synthesizeした結果です。 HogeViewControllerに追加したオブジェクトがアクセスするたびにallocされますが、UINavigationControllerで戻ってもviewDidLoadが呼ばれません。 よって全てのオブジェクトがメモリ内に残ったままです。
-(void)pageHoge {
HogeViewController *nextController = [[HogeViewController alloc] initWithNibName="HogeViewController" bundle:nil];
[self.navigationController pushViewController:nextController animated:YES];
[nextController release];
}
それでも@synthesizeが必要なときは、nilで判断するかないのかな???
-(void)addButton {
IButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(edit:) forControlEvents:UIControlEventTouchUpInside];
[self addSubView:button];
}
単純にbuttonのrelease忘れです。
これも忘れがちですが、UIButton等を動的にaddSubViewする場合、retainされたオブジェクトにしておくことです。
-(void)addButton {
UIButton *button = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; //retain
[button addTarget:self action:@selector(edit:) forControlEvents:UIControlEventTouchUpInside];
[self addSubView:button];
[button release]; //メモリ開放
}
retainしないでaddSubView後にreleaseするとアプリが落ちます。 これ外部の指摘で気づきました。 ※他にも多々そういうトピックがあるかと・・・ buttonWithType は init 系メソッドじゃないので、retain の必要ないので下記のコードで大丈夫です。
-(void)addButton {
IButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:@selector(edit:) forControlEvents:UIControlEventTouchUpInside];
[self addSubView:button];
}
まぁ、retain して release してもトータルプラマイゼロにはなると思いますが、意味がない・・・。
これらは、InstrumentsのLeaksを利用してメモリ変化が見られます。
勉強を始めた時には実感がなかったのですが、作ってみて初めて身にしみますw
メモリリーク対策のサイト ・How to avoid memory leaks in iPhone applications
AmericanTypewriter AmericanTypewriter-Bold <h3AppleGothic AppleGothic
ArialMT Arial-BoldMT Arial-ItalicMT Arial-BoldItalicMT
ArialRoundedMTBold
ArialUnicodeMS
Courier Courier-Bold Courier-Oblique Courier-BoldOblique
CourierNewPSMT CourierNewPS-BoldMT CourierNewPS-ItalicMT CourierNewPS-BoldItalicMT
DBLCDTempBlack
Georgia Georgia-Bold Georgia-Italic Georgia-BoldItalic
Helvetica Helvetica-Bold Helvetica-Oblique Helvetica-BoldOblique
HelveticaNeue HelveticaNeue-Bold
Hiragino Kaku Gothic ProN W3 HiraKakuProN-W3 Hiragino Kaku Gothic ProN W6 HiraKakuProN-W6
MarkerFelt-Thin
STHeitiJ-Light STHeitiJ-Medium
STHeitiK-Light STHeitiK-Medium
STHeitiSC-Light STHeitiSC-Medium
STHeitiTC-Light STHeitiTC-Medium
TimesNewRomanPSMT TimesNewRomanPS-BoldMT TimesNewRomanPS-ItalicMT TimesNewRomanPS-BoldItalicMT
TrebuchetMS TrebuchetMS-Bold TrebuchetMS-Italic TrebuchetMS-BoldItalic
Verdana Verdana-Bold Verdana-Italic Verdana-BoldItalic
Zapfino
LockClock-Light
PhonepadTwo
HKGPW3UI
OpenVPN設定していて、コマンドミスってブリッジ接続を有効になってしまい
サーバに全てのプロトコルで繋がらなくなった!!
自サーバとは言え、さすがに一瞬凍りついた(>_<)
一応、サーバ再起動して解決。
(1) Sassesのコンパネからログイン ※Sasses登録時のメールアドレスとパスワード
(2) サーバのステータスが表示される ※なかなか表示されないのでリロードした
(3) サーバの再起動 ※数分かかる
これ、サーバ起動時にブリッジ立ち上がる設定になってたら全てが終了だったよ・・・。 それにしても、VPSは自分でサーバ再起動できるのはよいねえ。
---2010/11/11 詳細手順、キャプチャーを追加
実機テストと言っても、初回の手順は結構大変です・・・
・キーチェーンアクセスで自己証明書の作成 ・iPhone Provisioning Portalに証明書を申請(アップロード) ※Safariでないとアップロードできません ・iPhone Provisioning Portalから証明書を取得(ダウンロード) ・キーチェーンアクセスに証明書を登録 ・iPhone Provisioning PortalでDevice情報を登録 ・iPhone Provisioning PortalでApp IDを登録 ・iPhone Provisioning Portalでプロビジョンプロファイルの作成 ・iPhone Provisioning Portalからプロビジョンプロファイルを取得(ダウンロード) ・Xcodeのオーガナイザでプロビジョンプロファイルを登録 ・Xcodeのプロジェクト設定でデバイスを設定 ・Xcodeのinfo.plistのBundle identifierにAppIDを設定 ・Xcodeから実機に自作アプリを転送
(1) キーチェーンアクセスを起動する。 (2) キーチェーンアクセス>証明書アシスタント>認証局に証明書を要求を選択する。 (3) 各項目を入力する。 ・ユーザのメールアドレス:AppleDeveloper登録した際のメールアドレス ・通称(コモンネーム):氏名 ・要求の処理:ディスクに保存 ・鍵ペア情報を指定:チェック (4) CertificateSigningRequest.certSigningRequest を任意の場所に保存する。 (5) RSA 2048ビットで【続ける】をクリックする。 (6) 証明書が作成される。
(1) Safariを開き、iOS Dev Centerにアクセスする ※Google Chromeだとアップできませんでした (2) Provisioning Portal にアクセスする。
(3) CertificatesのDevelopmentタブ画面を開き、【Request Certificate】をクリックする。
(4) 作成した証明書をアップロードする。
(1) Your Certificate 一覧に証明書が表示されているので【Download】で、cerファイルをダウンロードする。 ファイル名:developer_identity.cer
(2) click here to download now.のリンクをクリックし、AppleWWDRCA.cerをダウンロードする。 (3) キーチェンアクセスを開き、自分の証明書を選択する。 (4) developer_identity.cerをドラッグ&ドロップで追加。 ※この段階だと証明書が有効性がない
(5) AppleWWDRCA.cerをドラッグ&ドロップで追加する。
(1) Xcodeを起動し、ウィンドウ>オーガナイザを開く。
(2) DEVICESで自分のデバイスを選択し、identifierをコピーする。
(3) Provisioning PortalのDevicesを開き、【Add Device】をクリックする。
(4) 各項目を入力し【Submit】する。 Device Name:デバイス名 Device ID:オーガナイザでコピーしたidentifier
(1) Provisioning PortalのApp IDsを開く。 (2) 【New App ID】をクリックし、Description、Bundle Identifier (App ID Suffix)を入力し【Submit】する。 例) Description:任意だがアプリ名が良いか? Bundle Identifier: ドメイン.アプリ名
(1) Provisioning PortalのProvisioningを開く。 (2) 【New Provisioning】をクリックする。 (3) 各項目を入力し【Submit】する。 Profile Name:任意名を入力 Certificates:証明書を選択 Devices:利用するデバイスをチェック
(4) Development Provisioning Profiles一覧から、Provisioningファイルをダウンロードする。
(5) Provisioningファイルをダブルクリックすると、オーガナイザに登録される。
(1) Xcodeのプロジェクト>プロジェクト設定を編集を選択する。 (2) ビルドタブを選択しコード署名ID>Any iPhone OS Deviceを、作成したProvisioningに設定する。 (3) info.plistを開き、Bundle identifier を作成した App IDに設定する。 (4) Xcode【ビルドと実行】をDeviceに切り替えて実行する。
www.yoo-s.comのドメインをyoo-s.comで統一したい場合、.htaccessで設定するだけです。
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.yoo-s\.com
RewriteRule ^(.*) http://yoo-s.com/$1 [R=301,L]
www.yoo-s.comドメインを正規表現で取得し、301リダイレクトします。 $1を引数にすることで、下位階層のパスまで対応できます。
追記:2014/08/14
/etc/apache2/sites-available/default
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Order allow,deny
allow from all
AppleのiPhone OS View Controllerプログラミングガイドの日本語版が思いのほか充実している。 昔のドキュメントは英語ばっかだったんだけど。
NavigationControllerによる階層データの編集についても図がついていてわかりやすいです。
・AppleDeveloper「編集(Edit)」/「完了(Done)」ボタンの使用 ・Navigation Controllerの使用
CoreDataはメモリ上にデータを管理(NSManagedObjectContext)しているため、保存処理は十分注意する必要がある。
例えば、新規でレコードを作りそれをキャンセル(メモリ破棄)する場合、deleteObjectsで削除してコミット(save)すれば動作するでしょう。
新規でない場合、しかし、既にフェッチしたデータを編集する場合は注意です。 やっぱりキャンセルしようとdeleteObjectsを使うと、その名の通りデータが削除されてコミットされてしまいます。
NSManagedObjectContextに、saveやundo等の処理が定義されています。
- (NSSet *)insertedObjects;
- (NSSet *)updatedObjects;
- (NSSet *)deletedObjects;
- (NSSet *)registeredObjects;
- (void)undo;
- (void)redo;
- (void)reset;
- (void)rollback;
- (BOOL)save:(NSError **)error;
- (void)lock;
- (void)unlock;
- (BOOL)tryLock;
キャンセルする場合、差し当たりrollbackで良さそうだけどちょっと自信はない。。。 それぞれの挙動は、時間あったら調べておきます。
ちなみに、undoManagerってのも存在するので1つずつ戻すってことも簡単に(?)できそうです。
IBでなくXcodeでUIButtonを追加してみる。
IBでおなじみのボタンです。 UIButton.hに定義されています。
UIButtonTypeCustom = 0,
UIButtonTypeRoundedRect,
UIButtonTypeDetailDisclosure,
UIButtonTypeInfoLight,
UIButtonTypeInfoDark,
UIButtonTypeContactAdd,
UIButton buttonWithType:で設定します。
これは他のオブジェクトが利用するのでUIControllに定義されています。
UIControlEventTouchDown = 1 << 0, // on all touch downs
UIControlEventTouchDownRepeat = 1 << 1, // on multiple touchdowns (tap count > 1)
UIControlEventTouchDragInside = 1 << 2,
UIControlEventTouchDragOutside = 1 << 3,
UIControlEventTouchDragEnter = 1 << 4,
UIControlEventTouchDragExit = 1 << 5,
UIControlEventTouchUpInside = 1 << 6,
UIControlEventTouchUpOutside = 1 << 7,
UIControlEventTouchCancel = 1 << 8,
UIControlEventValueChanged = 1 << 12, // sliders, etc.
UIControlEventEditingDidBegin = 1 << 16, // UITextField
UIControlEventEditingChanged = 1 << 17,
UIControlEventEditingDidEnd = 1 << 18,
UIControlEventEditingDidEndOnExit = 1 << 19, // 'return key' ending editing
UIControlEventAllTouchEvents = 0x00000FFF, // for touch events
UIControlEventAllEditingEvents = 0x000F0000, // for UITextField
UIControlEventApplicationReserved = 0x0F000000, // range available for application use
UIControlEventSystemReserved = 0xF0000000, // range reserved for internal framework use
UIControlEventAllEvents = 0xFFFFFFFF
- (void) createButton(NSInteger) index {
UIButton *button = [UIButton buttonWithType: UIButtonTypeRoundedRect];
button.tag = index;
//button.titleLabel.text = @"ボタン"; //iphone3Gまで?
[button setTitle:@"C" forState:forState:UIControlStateNormal];
button.titleLabel.font = [UIFont systemFontOfSize: 12];
button.frame = CGRectMake(0.0f, 0.0f, 15.0f, 15.0f);
button.titleLabel.shadowOffset = CGSizeMake (1.0, 0.0);
[button addTarget:self action:@selector() forControlEvents:UIControlEventTouchUpInside];
- (void) editBar:(UIButton *)sender {
NSLog(@"---- editBar ----");
NSLog(@"%d", sender.tag);
}
tagはUIViewに定義されているプロパティですが、アプリケーション上のグループIDみたいなもののようです。 例えば複数のボタンを作成して、どのボタンがクリックされたかを連番のキーで判別するのもありかな?と。
CGRectMakeで座標(第1,2引数)とサイズ(第3,4引数)を指定します。
addTarget:でイベントを登録できます。 forControlEvents:はイベントの種類を指定します。
titleLabel.textはiOS4では利用できないみたいなので、setTitleで指定します。 その際、ボタンの状態も指定する必要があります。
UIControlStateNormal = 0,
UIControlStateHighlighted = 1 << 0, // used when UIControl isHighlighted is set
UIControlStateDisabled = 1 << 1,
UIControlStateSelected = 1 << 2, // flag usable by app (see below)
UIControlStateApplication = 0x00FF0000, // additional flags available for application use
UIControlStateReserved = 0xFF000000