いやぁ、まいったまいった。iOSアプリ開発をStoryBoard中心にやってるんだけど、ViewContorollerから別に作った、xibファイルをUINibに読み込んで使うことを試みてみたら、何か条件がそろうとメモリリークが起きるみたい。
調べれる範囲だと良かったんだけど、読み込んだNibを閉じた後の2回目のタッチでハングアップするという怪現象。タッチイベントのセレクターが開放されてしまったようで、イベントハンドラすら実行されない。
で、追跡できない状態。もしかしたら、別のViewがタッチを受け付けているかもしれないが、1回目は大丈夫で、2回目がダメというのが理解不能。
別のViewControllerで試したら普通に動くので、何か条件が整った時だけっぽい。
解決にあたり、かなり時間をさいてしまったが先に進まないといけないので、原因の究明よりも問題の解決を優先することに。UINibをインスタンス化しなければ、ハングアップが起きないという確証はとれたので、xibをObjective-Cに変換してみることをやってみた。しかも、PHPで。
Objective-C で作られた xibをObjective-Cに変換するアプリはあるみたい。
UIImage,UIImageViewとUILabelという今、必要な物しか実装していませんが、ソース貼り付けておきます。きっちり作っていく過程で他のOS向けにも出力できるようにすれば色々できそうですね。InterfaceBuilderを座標出しの道具として使うのもありですか?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
<?php $xib = new xib2code('abc.xib'); Class xib2code { private $xml; private $ech; function __construct($finename) { $this->xml = simplexml_load_file($finename); $this->ech = array(); $this->main(); } function main() { /* Resources section */ foreach ($this->xml->resources[0] as $xm) { switch ($xm->getName()) { case 'image': $this-> resource_image($xm); break; default: # code... break; } } /* Objects section */ foreach ($this->xml->objects[0]->view[0]->subviews->children() as $xm) { switch ($xm->getName()) { case 'imageView': $this->object_imageView($xm); break; case 'label': $this->object_label($xm); break; default: break; } } /* output */ foreach ($this->ech as $l) { echo $l."\n"; } } /* Resource Functions */ function resource_image($xm) { /*UIImage*/ $this->classCommentStart($xm,$this->ech[]); $cName = 'UI'.ucfirst($xm->getName()); $fname = $xm->attributes()->name; $id = $this->idHash($fname); $this->ech[] = 'NSString* '.$id.'_path'.' = [[NSBundle mainBundle] pathForResource:@"'.$fname.'" ofType:nil];'; $this->ech[] = $cName.'* '.$id.' = [['.$cName.' alloc] initWithContentsOfFile:'.$id.'_path'.'];'; $this->classCommentEnd($xm,$this->ech[]); } /* Object Functions */ function object_imageView($xm) { /*UIImage*/ /* 前準備 */ $this->classCommentStart($xm,$this->ech[]); $this->classAllocInitWithFrame($xm,$this->ech[]); $id = $this->idHash($xm->attributes()->id); /* image が設定されている場合は挿入 */ $xmlImg = $xm->attributes()->image; if (isset($xmlImg)) { $imgId = $this->idHash($xmlImg); $this->ech[] = $id.'.image = '.$imgId.';'; } /* addSubview */ $this->classAddSubview($xm,$this->ech[]); $this->classCommentEnd($xm,$this->ech[]); } function object_label($xm) { $this->classCommentStart($xm,$this->ech[]); $this->classAllocInitWithFrame($xm,$this->ech[]); $this->propatyTag($xm,$this->ech[]); $id = $this->idHash($xm->attributes()->id); $xmlNumberOfLine = $xm->attributes()->numberOfLines; if (isset($xmlNumberOfLine)) { $this->ech[] = $id.'.numberOfLines = '. intval($xmlNumberOfLine).';'; } $xmlTextAlignment = $xm->attributes()->textAlignment; if (isset($xmlTextAlignment)) { $this->ech[] = $id.'.textAlignment = NSTextAlignment'.ucfirst($xmlTextAlignment).';'; } if (isset($xm->fontDescription)) { $xmlFontFmily = $xm->fontDescription->attributes()->type; $xmlFontSize = $xm->fontDescription->attributes()->pointSize; if ((isset($xmlFontFmily)) && (isset($xmlFontSize))) { $this->ech[] = $id.'.font = [UIFont fontWithName:@"'.$xmlFontFmily.'" size:'.intval($xmlFontSize).'];'; } } if (isset($xm->color)) { $xmlTextColor = $xm->color->attributes()->cocoaTouchSystemColor; if (isset($xmlTextColor)) { /* ホントはもっと複雑、RGB指定とか対応出来てない */ $this->ech[] = $id.'.textColor = [UIColor '.$xmlTextColor.'];'; } } $xmlText = $xm->attributes()->text; if (isset($xmlText)) { /* ホントはもっと複雑、RGB指定とか対応出来てない */ $this->ech[] = $id.'.text = @"'.$xmlText.'";'; } $this->classAddSubview($xm,$this->ech[]); $this->classCommentEnd($xm,$this->ech[]); } /* Method Methods */ function classAllocInitWithFrame($xm,&$ech) { $cName = 'UI'.ucfirst($xm->getName()); $id = $this->idHash($xm->attributes()->id); $x = $xm->rect->attributes()->x; $y = $xm->rect->attributes()->y; $w = $xm->rect->attributes()->width; $h = $xm->rect->attributes()->height; $ech = $cName.'* '.$id.' = [['.$cName.' alloc] initWithFrame:CGRectMake('.$x.','.$y.','.$w.','.$h.')];'; } function classAddSubview($xm,&$ech) { $id = $this->idHash($xm->attributes()->id); $ech = '[self addSubview:'.$id.'];'; } /* Propaty Methods */ function propatyTag($xm,&$ech) { $id = $this->idHash($xm->attributes()->id); $xmlTag = $xm->attributes()->tag; if (isset($xmlTag)) { $ech = $id.'.tag = '. intval($xmlTag).';'; } } /* Utilyty */ function idHash($str) { return 'id'.hash('crc32b',$str); } function classCommentStart($xm,&$ech) { $cName = 'UI'.ucfirst($xm->getName()); $ech = '/* '.$cName.' start */'; } function classCommentEnd($xm,&$ech) { $cName = 'UI'.ucfirst($xm->getName()); $ech = '/* '.$cName.' end */'; } } ?> |
コメント