這篇文章還可以在這裏找到 英語
場景 4: 吃棒棒糖時閃退!
用戶郵件說, “當rage master吃棒棒糖時應用就閃退…” 另一用戶說, “我讓rage master 吃棒棒糖,沒幾次應用就閃退了!”
崩潰日誌如下:
Incident Identifier: 081E58F5-95A8-404D-947B-5E104B6BC1B1
CrashReporter Key: 5a56599d836c4f867f6eec76afee451bf9ae5f31
Hardware Model: iPhone4,1
OS Version: iPhone OS 6.0 (10A403)
Kernel Version: Darwin Kernel Version 13.0.0: Sun Aug 19 00:28:05 PDT 2012; root:xnu-2107.2.33~4/RELEASE_ARM_S5L8940X
Date: 2012-11-03 13:39:59 -0400
Time since snapshot: 4353 ms
Free pages: 968
Active pages: 7778
Inactive pages: 4005
Throttled pages: 92319
Purgeable pages: 0
Wired pages: 23347
Largest process: Rage Masters
|
Processes
Name <UUID> rpages recent_max [reason] (state)
lsd <6a9f5b5f36b23fc78f87b6d8f1f49a9d> 331 331 [vm] (daemon) (idle)
afcd <b0aff2e7952e34a9882fec81a8dcdbb2> 141 141 [vm] (daemon) (idle)
itunesstored <4e0cd9f873de3435b4119c48b2d6d13d> 1761 1761 [vm] (daemon) (idle)
softwareupdatese <2bc4b5ae016431c98d3b34f81027d0ae> 311 311 [vm] (daemon) (idle)
Amazon <4600481f07ec3e59a925319b7f67ba14> 2951 2951 [vm] (suspended)
accountsd <ac0fce15c1a2350d951efc498d521ac7> 519 519 [vm] (daemon) (idle)
coresymbolicatio <edba67001f76313b992056c712153b4b> 126 126 [vm] (daemon) (idle)
Skype <504cf2fe60cb3cdea8273e74df09836b> 3187 3187 [vm] (background)
MobileMail <bff817c61ce33c85a43ea9a6c98c29f5> 14927 14927 [vm] (continuous)
MobileSMS <46778de076363d67aeea207464cfc581> 2134 2134 [vm] (background)
MobilePhone <3fca241f2a193d0fb8264218d296ea41> 2689 2689 [vm] (continuous)
librariand <c9a9be81aa9632f0a913ce79b911f27e> 317 317 [vm] (daemon)
kbd <3e7136ddcefc3d77a01499db593466cd> 616 616 [vm] (daemon)
tccd <eb5ddcf533663f8d987d67cae6a4c4ea> 224 224 [vm] (daemon)
Rage Masters <90b45d6281e934209c5b06cf7dc4d492> 28591 28591 [vm] (frontmost) (resume)
ptpd <04a56fce67053c57a7979aeea8e5a7ea> 879 879 (daemon)
iaptransportd <f784f30dc09d32078d87b450e8113ef6> 230 230 (daemon)
locationd <892cd1c9ffa43c99a82dba197be5f09e> 1641 1641 (daemon)
syslogd <cbef142fa0a839f0885afb693fb169c3> 237 237 (daemon)
mediaserverd <80657170daca32c9b8f3a6b1faac43a2> 4869 4869 (daemon)
dataaccessd <2a3f6a518f3f3646bf35eddd36f25005> 1786 1786 (daemon)
aosnotifyd <d4d14f2914c3343796e447cfef3e6542> 549 549 (daemon)
wifid <9472b090746237998cdbb9b34f090d0c> 455 455 (daemon)
SpringBoard <27372aae101f3bbc87804edc10314af3> 18749 18749
backboardd <5037235f295b33eda98eb5c72c098858> 5801 5801 (daemon)
UserEventAgent <6edfd8d8dba23187b05772dcdfc94f90> 601 601 (daemon)
mediaremoted <4ff39c50c684302492e396ace813cb25> 293 293 (daemon)
pasteboardd <8a4279b78e4a321f84a076a711dc1c51> 176 176 (daemon)
springboardservi <ff6f64b3a21a39c9a1793321eefa5304> 0 0 (daemon)
syslog_relay <45e9844605d737a08368b5215bb54426> 0 0 (daemon)
DTMobileIS <23303ca402aa3705870b01a9047854ea> 0 0 (daemon)
notification_pro <845b7beebc8538ca9ceef731031983b7> 169 169 (daemon)
syslog_relay <45e9844605d737a08368b5215bb54426> 0 0 (daemon)
ubd <74dc476d1785300e9fcda555fcb8d774> 976 976 (daemon)
twitterd <4b4946378a9c397d8250965d17055b8e> 730 730 (daemon)
configd <4245d73a9e96360399452cf6b8671844> 809 809 (daemon)
absinthed.N94 <7f4164c844fa340caa940b863c901aa9> 99 99 (daemon)
filecoordination <fbab576f37a63b56a1039153fc1aa7d8> 226 226 (daemon)
distnoted <a89af76ec8633ac2bbe99bc2b7964bb0> 137 137 (daemon)
apsd <94d8051dd5f5362f82d775bc279ae608> 373 373 (daemon)
networkd <0032f46009f53a6c80973fe153d1a588> 219 219 (daemon)
aggregated <8c3c991dc4153bc38aee1e841864d088> 112 112 (daemon)
BTServer <c92fbd7488e63be99ec9dbd05824f5e5> 522 522 (daemon)
fairplayd.N94 <7bd896bd00783a48906090d05cf1c86a> 210 210 (daemon)
fseventsd <996cc4ca03793184aea8d781b55bce08> 384 384 (daemon)
imagent <1e68080947be352590ce96b7a1d07b2f> 586 586 (daemon)
mDNSResponder <3e557693f3073697a58da6d27a827d97> 295 295 (daemon)
lockdownd <ba1358c7a8003f1b91af7d5f58dd5bbe> 389 389 (daemon)
powerd <2d2ffed5e69638aeba1b92ef124ed861> 174 174 (daemon)
CommCenter <1f425e1e897d32e8864fdd8eeaa803a8> 2212 2212 (daemon)
notifyd <51c0e03da8a93ac8a595442fcaac531f> 211 211 (daemon)
ReportCrash <8c32f231b2ed360bb151b2563bcaa363> 337 337 (daemon)
|
這日誌跟我們前面見到的相差很多。
這個一個來自iOS 6的低內存崩潰日誌。正如我們前面所說的,低內存崩潰日誌與其他類型的崩潰日誌很不一樣,它們不指向特定的文件和代碼行。相反,它們畫出了閃退時設備上的內存使用情況的圖表。
至少,頭部還是跟其他崩潰日誌很像的: 提供了 Incident Identifier, CrashReporter Key, Hardware Model, OS Version等信息。
接下來部分是低內存崩潰日誌特有的:
-
Free pages 指可用內存頁數。每頁大小約是4KB, 上面的日誌中,可用內存約爲3,872 KB (或者說 3.9 MB)。
-
Purgeable pages 是那部分可被清除或重用的內存。在上面的日誌中,是0KB。
-
Largest process是閃退時使用大部分內存的應用名稱,在上面的日誌中,正是你的應用!
-
Processes顯示了閃退時各進程列表,還包含內存使用量。包含進程名 (第一列), 進程唯一標識符(第二名), 進程使用的內存頁數(第三列)。最後一列是每個應用的狀態。通常,發生閃退的應用的狀態是
frontmost。 這裏是 Rage Masters, 使用28591 頁 (or 114.364 MB) 內存——這內存太多了!
通過,最大進程和frontmost狀態的應用是相同的, 而且也是引起低內存閃退的應用進程。但是也可能看到最大進程和 frontmost狀態應用不同的例子。比如,如果最大進程是SpringBoard, 忽略它 , 因爲 SpringBoard 進程是顯示主屏幕的應用,出現在你雙擊home按鈕等情況,而且它是一直活動的。
低內存發生時,iOS向活動的應用發出低內存警告並終止後臺應用。如果前臺應用仍然繼續增長內存,iOS將終止它。
爲了查找低內存問題的原因,你必需使用Instruments剖析應用。如果你不知道怎麼做,可以看一下我們 一篇關於這個方面的教程.。 :] 另外, 你也可以走捷徑,響應低內存警告通知,以解決部分閃退問題。
回到Xcode查看RMLollipopLicker.m文件。 這是實現吃棒棒糖的視圖控制器。看看源代碼:
#import "RMLollipopLicker.h"
#define COUNT 20
@interface RMLollipopLicker ()
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UILabel *lickedTimeLabel;
@end
@implementation RMLollipopLicker {
NSOperationQueue *queue;
NSMutableArray *lollipops;
}
#pragma mark - Life cycle
- (void)viewDidLoad {
[super viewDidLoad];
self.progressView.progress = 0.0;
self.label.text = [NSString stringWithFormat:@"Tap on run and I'll lick a lollipop %d times!", COUNT];
self.lickedTimeLabel.text = @"";
lollipops = [[NSMutableArray alloc] init];
queue = [[NSOperationQueue alloc] init];
}
- (void)lickLollipop {
NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"Lollipop" withExtension:@"plist"];
NSDictionary *dictionary = [NSDictionary dictionaryWithContentsOfURL:fileURL];
NSString *lollipop = [dictionary objectForKey:@"Lollipop"];
[lollipops addObject:lollipop];
}
#pragma mark - IBActions
- (IBAction)doneButtonPressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)runButtonPressed:(id)sender {
[sender setEnabled:NO];
[queue addOperationWithBlock:^{
for (NSInteger i = 0 ; i = COUNT) {
self.label.text = [NSString stringWithFormat:@"Tap on run and I'll lick a lollipop %d times!", COUNT];
self.progressView.progress = 0.0;
[sender setEnabled:YES];
}
}];
}
}];
}
@end
|
當用戶點擊運行按鈕, 應用開始一個背景線程,調用 lickLollipop 方法若干次,然後更新界面反映吃棒棒糖的數量。 lickLollipop 方法從屬性列表文件(PLIST)文件讀取一個長字符串,然後添加到數組上。這些數據並不重要, 能在不影響用戶體驗的前提下重新創建。
利用每種能夠清除和重建數據而不影響用戶體驗的情況是好習慣。這樣能夠方便地釋放內存,減少低內存警告。
那麼,如何提高代碼質量呢? 實現 didReceiveMemoryWarning 方法,像下面這樣處理數據:
-(void)didReceiveMemoryWarning {
[lollipops removeAllObjects];
[super didReceiveMemoryWarning];
}
|
搞定!
下一步?
萬歲,你研究了4個閃退案例! 你的應用更完善了,並且學到了一些重要的調試技巧。
你可以到這裏下載改進後的項目代碼。
你喜歡iOS崩潰日誌揭祕嗎? 希望你能將學到的運用到你自己的應用中,也希望你能處理閃退,使你的應用更強壯!
如果你對本教程或崩潰日誌有問題或意見,可以在下面發表評論。
注:本人轉載此文章,僅爲以後學習方便!絕無他意!
轉自:http://www.raywenderlich.com/zh-hans/30863/ios%E5%BA%94%E7%94%A8%E5%B4%A9%E6%BA%83%E6%97%A5%E5%BF%97%E6%8F%AD%E7%A7%982