大致上會造成問題還是因為不熟的關係造成的。
因為不曉得怎麼透過 code 把 xib 檔內的 View 物件產生出來,所以一直在網路上找資訊,然後終於找的某個答案了之後,那就是一種答案了,先直接拿來用了再說,根本沒有細究。
// ------------
先建立繼承UIView的class,
接下來建立xib檔,並在xib中設定class為剛剛建立的class,
把xib內的物件和class link 起來,
並在initWithFrame中加入
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
NSArray *viewXib = [[NSBundle mainBundle] loadNibNamed:@"viewer" owner:self options:nil];
接下來建立xib檔,並在xib中設定class為剛剛建立的class,
把xib內的物件和class link 起來,
並在initWithFrame中加入
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
NSArray *viewXib = [[NSBundle mainBundle] loadNibNamed:@"viewer" owner:self options:nil];
self = [viewXib objectAtIndex:0];
}
return self;
}
return self;
}
// ------------
於是在弄了一堆有的沒有的之後,把它拿來改成類似這樣:
// ------------
- ( id ) initWithFrame: ( CGRect ) frame
{
self = [super initWithFrame: frame];
if ( nil == self )
{
return nil;
}
NSArray * pViewXib;
pViewXib = [[NSBundle mainBundle] loadNibNamed: @"xxxxView" owner: self options: nil];
// viewContainer 是成員變數.
// 想說用來把這個 xib 檔產生的 view object 記錄下來,方便後續要用到的時候用。
viewContainer = [[NSArray alloc] initWithArray: pViewXib];
return self;
}
然後在要建立&顯示此一整個 View 的地方的:
// ------------
{
// ... 前略 ...
xxxxView * pView;
pView = [[xxxxView alloc] initWithFrame: [[self view] frame]];
// ... 後略 ...
}
// ------------
因為 UI 的部分顯示都已經正常了,所以就以為已經搞定了,直到打算在這個 view 裡頭拿 touch event 出來用的時候,才發現問題大條了 ⋯
因為, viewContainer 裡頭的值竟然變成 nil 了。
再來,經過一番思索之後,本來打算寫成這樣的:
// ------------
+ ( id ) CreateWithFrame:(CGRect)frame
{
NSArray * pViewXib;
id idObject;
pViewXib = [[NSBundle mainBundle] loadNibNamed:@"xxxxView" owner: nil options:nil];
if ( nil == pViewXib )
{
return self;
}
idObject = nil;
for ( id idView in pViewXib )
{
if ( nil == idView )
{
continue;
}
if ( [idView isKindOfClass: [xxxxView class]] == YES )
{
idObject = idView;
}
}
if ( ( nil != idObject ) && ( [(xxxxOverlayView *)idObject viewContainer] == nil ) )
{
[(xxxxView *)idObject setViewContainer: [[NSMutableArray alloc] initWithArray: pViewXib]];
NSLog( @"view container: %@", [idObject viewContainer] );
}
return idObject;
}
// ------------
結果還是不行的噢,因為這個 owner: nil 的設定,會讓視窗物件的功能找不到主子,會死翹翹的。 button 按下去後會得到這樣的死掉訊息:
-[NSObject performSelector:withObject:withObject:]: message sent to deallocated instance 0x6c76a40
※ 因為有用畫面在該 View 裡頭的 button 設定 IBAction 的連結的關係,拿掉就不會當了;當然不會當了,不過 button 也沒作用了 =..="
關於這個問題的解法,反而容易多了,只要用把各個 button 物件取出,分別再替它們 addTarget 把 touch event 加回該 button 物件裡頭就能搞定了。
差別是這樣子處理完成之後,其實使用 xib 檔來設定各個 view 的資訊的動機就又更少了點,因為連 outlet 的設定都改成用 code 解決掉了啊。
----
理論上,在使用 xib 來產生 view 的一些問題,到這邊應該要告一段落了,
但是,還是會探究一下問題發生的問題點。
若是在建立 Xib UI 物件,繼續引用上面提到的從網路上找來並稍加修正的這個方式:
- ( id ) initWithFrame: ( CGRect ) frame
{
self = [super initWithFrame: frame]; // ※ 1.
if ( nil == self )
{
return nil;
}
NSArray * pViewXib;
pViewXib = [[NSBundle mainBundle] loadNibNamed: @"xxxxView" owner: self options: nil]; // ※ 2.
// viewContainer 是成員變數.
// 想說用來把這個 xib 檔產生的 view object 記錄下來,方便後續要用到的時候用。
viewContainer = [[NSArray alloc] initWithArray: pViewXib]; // ※ 3.
return self;
}
※刪除線的部份是發現,描述有點錯誤,晚上追加的修正(寫錯了的意思 =..=)。
當此 ※ 1 執行後, 會先產生一個 一個 view Object 出來,過程順利的話,會在 ※ 2 的地方再透過 Xib 檔案,另外再產生一個 view Object 出來,然後,實際上此函數回傳給呼叫者的物件,不是透過這個由 Xib 檔案產生的這一個,而且回傳之後,沒有用來做其它太特殊的操作。
在這樣子的狀況之下,使用 ※ 1 所產生出了的 view Object 似乎變成多餘的了。
而且,在系統機制運作之下,也可能會造成忘記釋放這一塊記憶體的問題。
而且,在系統機制運作之下,也可能會造成忘記釋放這一塊記憶體的問題。
※ 然後,我一直沒有注意到的地方就是在此處。
當我使用 ※ 3 這個將 viewContainer 成員變數建立並 assign 一些初始值的時候,這個 viewContainer 其實是屬於 self = [super initWithFrame: frame]; 這個指令所創造的,
可是,事後在畫面控制上不管是 button action 的 IBAction ,或者之後追加的 touchBegan 的 Event,一直取不到 viewContainer 的內容,是因為後面這些畫面操作控制,其實都是在操作透過 [[NSBundle mainBundle] loadNibNamed: @"xxxxView" owner: self options: nil]; 所產生的物件,所以難怪一直無法正常取得該成員變數內的資訊了啊!
因為是完全不同的物件,而且,也沒有在過程裡頭賦予它們值。
結論,大概就整理出這樣子的內容了。
----
為什麼這麼簡單的錯誤,一直找不到問題呢?
1、 在開發試玩的功能是 UIImagePickerController 裡頭的 Camera ,很不巧的 這拍照功能無法使用模擬器進行測試。
2、 公司用 XCode 版本還有點舊,因為一些因素,目前它的狀況處於實機操作 Debug 中斷不能的狀況;所以只能使用 NSLog 輸出至 console 裡頭來找資訊判斷。
所以在試了很多可能性的資訊輸出之後,才發現原來被拿來控制的記憶體內容,根本和預想的內容完全不一樣。
因為這樣的低級錯誤 & 正所謂屋漏偏逢連夜雨,花掉了不少時間在找這個問題!
所以就算錯誤很低級,還是花些時間記錄一下。 >"<
因為是完全不同的物件,而且,也沒有在過程裡頭賦予它們值。
結論,大概就整理出這樣子的內容了。
----
為什麼這麼簡單的錯誤,一直找不到問題呢?
1、 在開發試玩的功能是 UIImagePickerController 裡頭的 Camera ,很不巧的 這拍照功能無法使用模擬器進行測試。
2、 公司用 XCode 版本還有點舊,因為一些因素,目前它的狀況處於實機操作 Debug 中斷不能的狀況;所以只能使用 NSLog 輸出至 console 裡頭來找資訊判斷。
所以在試了很多可能性的資訊輸出之後,才發現原來被拿來控制的記憶體內容,根本和預想的內容完全不一樣。
因為這樣的低級錯誤 & 正所謂屋漏偏逢連夜雨,花掉了不少時間在找這個問題!
所以就算錯誤很低級,還是花些時間記錄一下。 >"<
沒有留言:
張貼留言