Thursday, January 26, 2012

objective-C Slice NSArray

あまり使わないかも知れないけれど


NSArray *array = [NSArray arrayWithObjects:@"Python", @"Objective-C", @"JavaScript", @"Erlang", nil];
NSRange range = NSMakeRange(1, 3);
NSLog(@"objectsAtIndexes(1, 2, 3):%@",[array subarrayWithRange:range]);



NSMakeRangeで開始indexとlengthを指定してNSRangeを作る。とこんな感じ。

> objectsAtIndexes(1, 2, 3):(
"Objective-C",
JavaScript,
Erlang
)

Wednesday, January 25, 2012

NavigationBarの位置がずれ, Status barの裏に描画されてしまう

iPhoneに内蔵されているPhotosアプリのように、画像をフルスクリーンで表示する際
ステータスバーを隠すため、setStatusBarHidden:を呼び出すことがあります。

ステータスバーをhidden=YESにしたとき、ナビゲーションバーの位置はそのままですが、
ここで、Homeボタンを押し、もう一度アプリを起動すると
ナビゲーションバーの位置はステータスバーの無いwindowでの位置に移動してしまいます。

また、フルスクリーンのViewをFadeoutするときに、ステータスバーをhidden=NOにしても
ナビゲーションバーの位置は動かず、ステータスバーの裏に表示されます。

どうやらiosのステータスバーの表示・非常時とナビゲーションバーの位置の移動は
連動しないように設計されているようです。

ですが、繰り返しになりますが、
アプリをバックグラウンドへまわしてもう一度フォアグラウンドへ戻したときは
ナビゲーションバーの位置が新しくセットされてしまうので、

この点は注意しなければいけないようです。





結局ステータスバーをhidden=NOにするときに一度ナビゲーションバーを非表示にし、すぐに表示しなおすことで
位置の修正をしました。




@implementation FirstViewController{
UIView *overView;
}

#pragma mark - View lifecycle
- (void)loadView
{
[super loadView];
UIApplication *app = [UIApplication sharedApplication];

overView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
overView.backgroundColor = [UIColor whiteColor];
overView.alpha = 0.0f;
overView.userInteractionEnabled = NO;
[app.keyWindow addSubview:overView];
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UIApplication *app = [UIApplication sharedApplication];

if(app.statusBarHidden == NO){
[app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];
[UIView animateWithDuration:0.4f animations:^(void){
overView.alpha = 1.0f;
}];

} else {
[app setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];

// hiding / showing navigationBar
[self.navigationController setNavigationBarHidden:YES];
[self.navigationController setNavigationBarHidden:NO];

[UIView animateWithDuration:0.4f animations:^(void){
overView.alpha = 0.0f;
}];
}
}

Wednesday, January 18, 2012

Debug Build. Delay of invocation of dealloc method.

With ARC and MRC mixed project, I found an delay of invocation of dealloc method.

When you assign a retained object to weak variable, this object will be released after the assignment immediately.
If you add the variable to a mutable array, it'll crash.

Because that we can not add nil to NSMutableArray.

But this crash happened only when the application was built by Release Build counfiguration.

When the application was built by Debug Build configuration, the crash did not happen.
I think the reason why the difference happened is the delay of invocation of dealloc method.

For example, I assign a retained object to weak variable 'obj'.
And then I add the
variable to a mutable array.
- (void)loadView
{
[super loadView];
__weak MyObject* obj = [MyObject instance];

NSMutableArray *arrayM = [NSMutableArray array];
[arrayM addObject:obj];
NSLog(@"object was inserted to array.");
}



MyObject is a custom object with MRC (-fno-obj-arc flagged).
@implementation MyObject
+ (id)instance
{
return [[[self alloc]init] autorelease];
}

- (void)dealloc
{
NSLog(@"dealloc");
[super dealloc];
}
@end



In the case of Release Build configuration, the dealloc method invoked before add to mutable array.
and it crash.
012-01-18 16:56:15.353 WhatTheNSMutableArray[3096:707] dealloc
2012-01-18 16:56:15.358 WhatTheNSMutableArray[3096:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x3717a8bf 0x318481e5 0x370cf20f 0x2651 0x3274d78b 0x3274bf9d 0x3273e941 0x327b0541 0x24d3 0x3274c7eb 0x327463bd 0x32714921 0x327143bf 0x32713d2d 0x31287df3 0x3714e553 0x3714e4f5 0x3714d343 0x370d04dd 0x370d03a5 0x32745457 0x32742743 0x2331 0x22dc)
terminate called throwing an exception(gdb)



But in the case of Debug Build configuration, the dealloc method invoked AFTER add to mutable array.
In spite of wrong code, it does NOT CRASH.
2012-01-18 17:24:36.342 WhatTheNSMutableArray[3175:707] object was inserted to array.
2012-01-18 17:24:36.352 WhatTheNSMutableArray[3175:707] dealloc



I should be careful to this delay. because i can't found the weak assignment mistake.

You can easily find a similar code. like this, but this is wrong.
__weak ASIHTTPRequest *request = [[ASIHTTPRequest alloc] initWithURL:...

[request setCompletionBlock:^{
[listOfResponseData addObject: request.responseData];
}];


Correctly as follows:
ASIHTTPRequest *_request = [[ASIHTTPRequest alloc] initWithURL:...
__weak ASIHTTPRequest *request = _request;
[request setCompletionBlock:^{
[listOfResponseData addObject: request.responseData];
}];

Tuesday, January 10, 2012

implement Accessor Method, Objective-C

see "Property Declaration Attributes" , Objective-C Programming Language > Declared Properties
http://t.co/JpxDVNHs

example: In this case, a RootViewController has "myStatus" property. I implemented accessor methods of this.
The setter method will set a value to the private instance "_myStatus" and text of "myLabel".
The getter method will return the instance value.


#import
typedef enum {
MyStatusTypeFine,
MyStatusTypePrettyGood
} MyStatusType;

@interface RootViewController : UIViewController

@property (setter = setMyStatus:, getter = getMyStatus) MyStatusType myStatus;
@property (strong) UILabel *myLabel;
@end



@implementation TopViewController{
MyStatusType _myStatus;
}
@synthesize myStatus = _myStatus;
@synthesize myLabel;

- (void)setMyStatus:(MyStatusType)myStatus
{
_myStatus = myStatus;
switch (myStatus) {
case MyStatusTypeFine:
self.myLabel.text = @"Fine.";
[self.myLabel sizeToFit];
self.myLabel.center = self.view.center;
break;

case MyStatusTypePrettyGood:
self.myLabel.text = @"Pretty good.";
[self.myLabel sizeToFit];
self.myLabel.center = self.view.center;
break;

default:
break;
}
}

- (MyStatusType)getMyStatus
{
return _myStatus;
}


#pragma mark - View lifecycle
- (void)loadView
{
[super loadView];

self.myLabel = [UILabel new];
[self.view addSubview: self.myLabel];

// set status
self.myStatus = MyStatusTypeFine;
}

Tuesday, August 02, 2011

退職しました


2011年 4月 22日 カリフォルニア州 Alviso Marina County Park にて撮影

 この度、先日の7月31日をもちまして、2010年に入社し1年4ヶ月勤めさせていただきましたヤフー株式会社を退職させていただきました。
 このご報告より前に、お気づきになられていた方もいらっしゃるようですが、僕は七夕の7月7日に最終出社日を迎え、それからは有給消化期間を過ごしながら新しい生活への準備を整えておりました。
 皆様へのご報告は退職日を迎えてからと決めておりましたので、改めまして正式なご報告をさせていただきます。

 ヤフーに入社してから仮配属でサービスの運用に携わり、運用ツールの開発、本配属後は担当サービスのフロントエンド開発に携わりました。特に本配属後に接したアジャイルスクラム手法は、デザイナーとエンジニアでチームを組んでの開発で、それまでのぼくの世界観を大きく広げる経験でした。半年間の内定者研修は長いものでしたが、仮配属の3ヶ月と本配属の6ヶ月を思い返すと、とても短い間にたくさんのことを勉強をさせていただきました。幸いなことに友人、先輩、上司、配属先にも恵まれ、とても良い9ヶ月を送ることができました。
 特に僕の開発や業務での直すべき点について指摘してくださり、叱ってくださった先輩、上司には本当に感謝しております。



 退職の理由については、自分の人生の方向をすこしだけ修正したいと考えたからです。

 僕がいわゆる就活を経験した時期は、ちょうど就職氷河期再来といわれた2009年(2010年卒)でしたが、僕は一度に何社も受けるような就活をしたくなかったので、いくつか会社説明会に参加させていただいた後、ヤフーの一社だけにアプライさせていただきました。

 「webの世界で生きていきたい」と決めていた学生時代、ヤフーに内定をいただいたときは本当にうれしくて、毎晩のように自分の世界が広がっていくイメージを思い描いておりました。
 
 そして入社前にカリフォルニアのwhere2.0カンファレンスを知り、ヤフーに入ったら絶対行くんだと心に決めて1年間を過ごし、今年の4月に有給をいただいてwhere2.0カンファレンス2011に参加して参りました。

 カリフォルニアで目にしてきたものは本当に刺激的で、お会いした方々から大きな影響を受けました。入社前に描いたイメージが結果的に退職の決意を後押しすることになるとは、入社当時では考えもしなかったことです。

 カリフォルニアでのホテルへの帰り道で、「人生の方向が見えてきてた」
  http://a.2tanb.com/qWASLR
とつぶやいたあの瞬間、自分の世界をもっと広げられるとイメージできた瞬間でした。



 こんな人生の選択ができる自分は、本当に幸せだと思っています。それはヤフーに入って、たくさんの人たちに出会い、いろいろな経験を積むこと無しにはできない選択でした。ヤフーでの1年数ヶ月は、何度も何度も自分の今とこれからを見つめ直す機会を与えてくれました。とても感謝しております。

 短い間でしたが、本当にありがとうございました。
 
 今後もwebの世界で生きていくことになりますが、少しの間自分の世界を広げるための準備に時間を取ろうと考えています。
 その間は、無職という形になりますが、みなさまこれからもどうぞよろしくお願い致します。

Tomonori TANABE