iPhone開發疑難雜症彙總
程式設計中總會遇到各種各樣的問題,這裡對出現的一些問題進行彙總,不斷補充
1. 野指標錯誤,使用了一個已經被釋放了的指標,會導致程式崩潰。
如果一個物件註冊了通知,但是在其dealloc的時候,並沒有作remove操作,當通知中心向其發通知的時候,並不知道這個物件已經釋放了,就會呼叫原指標地址的方法,導致出現野指標錯誤崩潰。
appTest[64158:fe03] -[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20
2012-06-08 17:09:14.813 appTest[64158:fe03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UITableViewCell atestFun:]: unrecognized selector sent to instance 0x6bceb20'
*** Call stack at first throw:
(
0 CoreFoundation 0x028bcbe9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x02a115c2 objc_exception_throw + 47
2 CoreFoundation 0x028be6fb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0282e366 ___forwarding___ + 966
5 Foundation 0x00d996c1 _nsnote_callback + 145
6 CoreFoundation 0x02894f99 __CFXNotificationPost_old + 745
7 CoreFoundation 0x0281433a _CFXNotificationPostNotification + 186
8 Foundation 0x00d8f266 -[NSNotificationCenter postNotificationName:object:userInfo:] + 134
9 Foundation 0x00d9b5a9 -[NSNotificationCenter postNotificationName:object:] + 56
又一次的執行,原因相同,但細節不同,這次是NSCFNumber
2012-06-09 10:14:39.823 appTest[65900:fe03] -[NSCFNumber atestFun:]: unrecognized selector sent to instance 0x6e639a0
2012-06-09 10:14:39.928 appTest[65900:fe03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber atestFun:]: unrecognized selector sent to instance 0x6e639a0'
*** Call stack at first throw:
典型的野指標問題
指標亂指,即原地址已經被分配給另外的物件使用了,再進行方法呼叫就會出錯
如果指標指向了一個autorelease的物件,也可能會出現這個問題,需要注意。
多釋放物件也會造成錯誤
2. 呼叫不存在的方法,這個問題在按鈕的呼叫中出現較多,即呼叫了一個不存在的方法,一般是有編譯告警的,程式設計的時候需要注意告警資訊。也就是說,系統在呼叫的時候,並沒有執行一個 [aObject responsToSelector:fun] 判斷,通過crash來暴露問題提示給使用者
又如:靜態方法中呼叫了非靜態方法,也會有告警,執行崩潰。值得注意的是,在靜態方法中使用 performSelector:@selector(static_fun2) 呼叫另外一個靜態方法static_fun2,是沒有問題的,這裡提出這個問題是因為performSelector看起來是一個非靜態的方法。
3. 陣列越界
4. 指標的使用
5. 使用一些系統類的時候,如UITableViewController 的時候,其tableView可能被釋放,不好控制,在出現問題的時候需要留意
6. 記憶體洩露,如果一個方法裡存在記憶體洩露的問題,並且這個方法會被頻繁呼叫,當洩露的記憶體到了一定大小的時候,會出現問題,所以必須關注記憶體洩露的問題
----
//7-9
除錯
po obj_name
檢視一個物件的值(內容),po means print object
gdb的除錯命令都是可以使用的,在有些時候,可以根據地址來進行檢視
如
p *((Class_name *)0x2322c2)
(gdb)p *((UIButton*)0x6d98ce0)
$1 = {
<UIControl> = {
<UIView> = {
<UIResponder> = {
<NSO
_backgroundView = 0x6dc0210,
_imageView = 0x0,
_titleView = 0x6dc00c0,
_initialized = 1 '\001',
(gdb)po 0x6dc00c0
<UIButtonLabel: 0x6dc00c0; frame = (15 6; 58 22); text = '記錄'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6dc02d0>>
(gdb)