読者です 読者をやめる 読者になる 読者になる

定食屋おろポン

おろしポン酢と青ネギはかけ放題です

NaNをcontainsなCGRectをViewのframeにSetしたらDied

僕がiOS開発を初めてから、今までに一番多く書いたコードは

NSLog(@"hoge.frame:%@", NSStringFromCGRect(hoge.frame));

のような気がします。
今日もCGRect周りでハマりました。表示されるべきViewが表示されない。不注意な僕にはよくあることです。
調査のなかで、先述のNSLog(@"hoge.frame:%@", NSStringFromCGRect(hoge.frame));をしてみると
hoge.frame:{{nan, 50}, {200, 200}};
との表示が。そりゃframeにnanが含まれてたら表示されないですよね。ハハハこやつめ。
しかし、問題はここから。

rect = ...;
NSLog(@"rect:%@", NSStringFromCGRect(rect));
view.frame = rect;
NSLog(@"view.frame:%@", NSStringFromCGRect(view.frame));

// Output
rect:{{50, 50}, {200, 200}};
view.frame:{{nan, 50}, {200, 200}};

こんなことになっていたわけです。代入するrectは問題無いのに、代入されたview.frameは不正な値を取っている。その時は「へー、viewのframeがNaNを含んでたら、そのあとで正しいRectを突っ込んでも反映されないのかな。気をつけようっと。あれ、でも除数の0チェックはしてるのにオカシイなー」くらいに思っていたのですが、どうも気になってさっき試してみました。(ちなみに不具合の原因は他のところにあってさくっと直しました)

@implementation NRViewController
{
    UIView*     _aView;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    _aView = [[UIView alloc] initWithFrame:CGRectMake(100.0f, 100.0f, 100.0f, 100.0f)];
    [_aView autorelease];
    _aView.backgroundColor = [UIColor blackColor];
    
    [self.view addSubview:_aView];
}

- (IBAction)setRectButtonAction:(UIButton *)sender {
    CGRect rect;
    rect = CGRectMake(50.0f, 50.0f, 200.0f, 200.0f);
    
    _aView.frame = rect;
}

- (IBAction)setInvalidRectAction:(UIButton *)sender {
    CGRect rect;
    rect = CGRectMake(0.0f / 0.0f, 50.0f, 200.0f, 200.0f);
    
    _aView.frame = rect;
}

適当に作ったViewに、NaNを含んだRectを突っ込んで...と。
結果は。。

2012-05-30 22:47:55.338 NaNRectSample[3437:f803] *** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan 150]'
*** First throw call stack:
(0x13c8022 0x1559cd6 0x1370a48 0x13709b9 0x1d8ec0d 0x1d84f55 0x1d84a0a 0x45fb8 0x31ce 0x13c9e99 0x1514e 0x150e6 0xbbade 0xbbfa7 0xbb266 0x3a3c0 0x3a5e6 0x20dc4 0x14634 0x12b2ef5 0x139c195 0x1300ff2 0x12ff8da 0x12fed84 0x12fec9b 0x12b17d8 0x12b188a 0x12626 0x27b2 0x2725)
terminate called throwing an exception(lldb) 

代入時に死にました。
だとしたら、view.frame:{{nan, 50}, {200, 200}};といったnanを含んだframeがなぜ存在していたのだろう。
まだ調査が必要ですね。