2011-05-12 77 views
1

我做一個UISegmentedControl Web服務請求,當我改變segmentedItem,並要求快速應用程序崩潰與此消息:調試消息

[會話開始於2011-05-12 十時58分50秒+0200。]終止於 迴應SpringBoard的終止。

[會話開始於2011-05-12 11時06分31秒+0200] GNU GDB 6.3.50-20050815(蘋果版GDB-1516)(週五2月11日6點19分43秒UTC 2011 )版權2004免費軟件 Foundation,Inc. GDB是GNU General Public 許可的免費軟件, ,在某些情況下,歡迎您將它改爲 並/或發佈它的副本 。鍵入「顯示 複製」以查看條件。對於GDB, 絕對沒有保證。 輸入「顯示保修」以獲取詳細信息。這個 GDB被配置爲 「--host = i386-apple-darwin --target = arm-apple-darwin」.tty/dev/ttys001將程序加載到 調試器中...程序已加載。靶向 遠程移動 /tmp/.XcodeGDBRemote-239-58切換 到遠程MacOSX的協議MEM爲0x1000 0x3fffffff緩存MEM 0x40000000之後 0xffffffff的無MEM 00000000 0x0fff 沒有運行運行... [切換到線程 11779] [切換到線程11779] sharedlibrary apply-load-rules全部 繼續編程接收信號: 「SIGKILL」。警告:無法讀取 符號 /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.3 (8J2)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (文件未找到)。殺戒

調試器已退出,狀態 0(GDB)

有誰知道我怎麼能解決這個問題的想法? 這是一個問題,因爲我沒有使用NSOperationQueue? 如果有的話,任何建議如何我可以解決這個問題將非常歡迎。 運行時無法找到任何內存泄漏。我跑了

下一次得到了記錄此消息:

程序接收到的信號:「EXC_BAD_ACCESS」。 警告:無法讀取/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.3(8J2)/符號/開發人員/usr/lib/libXcodeDebuggerSupport.dylib(未找到文件)的符號。 (GDB)

這裏是用於開始連接的代碼:

類的頭ServiceGetChildren:

#import <Foundation/Foundation.h> 

@class Authentication; 
@class AttendanceReportViewController; 

@interface ServiceGetChildren : NSObject { 

Authentication *authentication; 
AttendanceReportViewController *attendanceReportViewController; 

NSString *username; 
NSString *password; 
NSMutableString *authenticationString; 
NSString *encodedLoginData; 
NSMutableData *responseData; 
NSMutableArray *childrensArray; 
} 

@property (nonatomic, retain) NSString *username; 
@property (nonatomic, retain) NSString *password; 
@property (nonatomic, retain) NSMutableString *authenticationString; 
@property (nonatomic, retain) NSString *encodedLoginData; 
@property (nonatomic, retain) NSMutableData *responseData; 
@property (nonatomic, retain) NSMutableArray *childrensArray; 

- (void)startService:(NSURL *)url :(NSString *)method withParent:(UIViewController *)controller; 

@end 

類處理請求:

#import "ServiceGetChildren.h" 
#import "JSON.h" 
#import "Base64.h" 
#import "AttendanceReportViewController.h" 
#import "Authentication.h" 

@implementation ServiceGetChildren 

@synthesize appDelegate; 

@synthesize username; 
@synthesize password; 
@synthesize authenticationString; 
@synthesize encodedLoginData; 
@synthesize responseData; 
@synthesize childrensArray; 

- (id) init { 

if ((self = [super init])) { 

} 
return self; 
} 

- (void)startService:(NSURL *)url :(NSString *)method withParent:(UIViewController *)controller { 

username = appDelegate.username; 
password = appDelegate.password; 

attendanceReportViewController = (AttendanceReportViewController *)controller; 

Authentication *auth = [[Authentication alloc] init]; 
authenticationString = (NSMutableString*)[@"" stringByAppendingFormat:@"%@:%@", username, password];  
encodedLoginData = [auth encodedAuthentication:authenticationString]; 
[auth release]; 

// Setup up the request with the url 
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url 
                 cachePolicy: NSURLRequestReloadIgnoringCacheData 
                timeoutInterval: 20.0]; 
[request setHTTPMethod:method]; 
[request setValue:[NSString stringWithFormat:@"Basic %@", encodedLoginData] forHTTPHeaderField:@"Authorization"]; 

NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; 

// Display the network indicator when the connection request started 
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 

// Check that the NSURLConnection was successful and then initialize the responseData 
if(connection) { 
    NSLog(@"Connection made"); 
    responseData = [[NSMutableData data] retain]; 
} 
else { 
    NSLog(@"Connection could not be made"); 
} 
} 

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { 


[responseData setLength:0]; 

} 

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { 

[responseData appendData:data]; 
} 

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 

NSLog(@"Connection finished loading."); 
// Dismiss the network indicator when connection finished loading 
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

// Parse the responseData of json objects retrieved from the service 
SBJSON *parser = [[SBJSON alloc] init]; 

NSString *jsonString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; 
NSDictionary *jsonData = [parser objectWithString:jsonString error:nil]; 
NSMutableArray *array = [jsonData objectForKey:@"Children"]; 

childrensArray = [NSMutableArray arrayWithArray:array]; 

// Callback to AttendanceReportViewController that the responseData finished loading 
[attendanceReportViewController loadChildren]; 

[connection release]; 
[responseData release]; 
[jsonString release]; 
[parser release]; 
} 

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { 
NSLog(@"Connection failure."); 
NSLog(@"ERROR%@", error); 
// Dismiss the network indicator when connection failure occurred 
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 
[connection release]; 
// Inform the user that the server was unavailable 
} 

- (void) dealloc { 

[attendanceReportViewController release]; 
[super dealloc]; 
} 

類報頭AttendanceReportViewController :

#import <UIKit/UIKit.h> 

@class ServiceGetGroups; 
@class ServiceGetChildren; 
@class DetailViewController; 

@interface AttendanceReportViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> { 

ServiceGetGroups *serviceGetGroups; 
ServiceGetChildren *serviceGetChildren; 
DetailViewController *detailViewController; 

UISegmentedControl *segmentedControl; 
IBOutlet UIToolbar *groupsToolbar; 
NSMutableArray *btnArray; 
NSInteger index; 

IBOutlet UITableView *theTableView; 
IBOutlet UILabel *attendanceLabel; 
IBOutlet UILabel *abscentLabel; 
IBOutlet UILabel *totalLabel; 

NSMutableDictionary *selectRequestDictionary; 
NSMutableDictionary *selectNameDictionary; 

NSMutableArray *groupsArray; 
NSMutableArray *childrensArray; 
NSDictionary *childrensDictionary; 

NSURL *url; 
} 

@property (nonatomic, retain) ServiceGetGroups *serviceGetGroups; 
@property (nonatomic, retain) ServiceGetChildren *serviceGetChildren; 
@property (nonatomic, retain) DetailViewController *detailViewController; 

@property (nonatomic, retain) IBOutlet UIToolbar *groupsToolbar; 
@property (nonatomic, retain) IBOutlet UITableView *theTableView; 
@property (nonatomic, retain) IBOutlet UILabel *attendanceLabel; 
@property (nonatomic, retain) IBOutlet UILabel *abscentLabel; 
@property (nonatomic, retain) IBOutlet UILabel *totalLabel; 
@property (nonatomic, retain) UISegmentedControl *segmentedControl; 
@property (nonatomic) NSInteger index; 

@property (nonatomic, retain) NSMutableArray *btnArray; 
@property (nonatomic, retain) NSMutableDictionary *selectRequestDictionary; 
@property (nonatomic, retain) NSMutableDictionary *selectNameDictionary; 

@property (nonatomic, retain) NSMutableArray *groupsArray; 
@property (nonatomic, retain) NSMutableArray *childrensArray; 
@property (nonatomic, retain) NSDictionary *childrensDictionary; 

@property (nonatomic, retain) NSURL *url; 

- (void)setupSegmentedControl; 

- (void)requestGroups; 

- (void)requestChildren:(NSNumber *)groupId; 

- (void)loadGroups; 

- (void)loadChildren; 

@end 

類的採用UISegmentedControl:

#import "JSON.h" 
#import "AttendanceReportViewController.h" 
#import "CustomCellViewController.h" 
#import "DetailViewController.h" 
#import "ServiceGetGroups.h" 
#import "ServiceGetChildren.h" 
#import "Group.h" 
#import "Child.h" 

@implementation AttendanceReportViewController 

@synthesize serviceGetGroups; 
@synthesize serviceGetChildren; 
@synthesize detailViewController; 

@synthesize segmentedControl; 
@synthesize groupsToolbar; 
@synthesize index; 
@synthesize btnArray; 

@synthesize theTableView; 
@synthesize attendanceLabel; 
@synthesize abscentLabel; 
@synthesize totalLabel; 

@synthesize selectRequestDictionary; 
@synthesize selectNameDictionary; 

@synthesize groupsArray; 
@synthesize childrensArray; 
@synthesize childrensDictionary; 

@synthesize url; 
#pragma mark - 
#pragma mark View lifecycle 

// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. 
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { 
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
if (self) { 
    // Custom initialization. 
} 
return self; 
} 

- (void)requestGroups { 

NSURL *groupsURL = [NSURL URLWithString:@"http://services/groups"]; 
[serviceGetGroups startService:groupsURL :@"GET" withParent:self]; 
} 

- (void)requestChildren:(NSNumber *)groupId { 
NSLog(@"%@", groupId); 

NSString *baseURL = @"http://services/group/"; 
NSString *method = [NSString stringWithFormat:@"%@%@", groupId, @"/children"]; 
NSString *theURL = [NSString stringWithFormat:@"%@%@", baseURL, method]; 

self.url = [NSURL URLWithString:theURL]; 

NSLog(@"%@", self.url); 

[serviceGetChildren startService:self.url :@"GET" withParent:self]; 
} 

- (void)loadGroups { 
// Retrieve a array with dictionaries of groups from ServiceGetGroups 
self.groupsArray = [[serviceGetGroups.groupsArray copy] autorelease]; 

// The array to hold segmentedItems for the segmentedControl, representing groups buttons 
btnArray = [NSMutableArray arrayWithObjects: @"Alla", nil]; 

for (NSDictionary *groupDict in groupsArray) { 
    // Add each groups name to the btnArray as segmentedItems for the segmentedControl 
    [btnArray addObject:[groupDict objectForKey:@"Name"]]; 
} 

// Create a new NSMutableDictionary with group names as keys and group id´s as values 
// used for reference to segementedControl items to make request to serviceGetChildren 
self.selectRequestDictionary = [NSMutableDictionary dictionary]; 
for (NSDictionary *dict in groupsArray) { 
    [selectRequestDictionary setObject:[dict objectForKey:@"Id"] forKey:[dict objectForKey:@"Name"]]; 
} 

// Create a new NSMutableDictionary with group id´s as keys and group names as values 
// used for retrieving a groupName from a passed id 
self.selectNameDictionary = [NSMutableDictionary dictionary]; 
for (NSDictionary *dict in groupsArray) { 
    [selectNameDictionary setObject:[dict objectForKey:@"Name"] forKey:[dict objectForKey:@"Id"]]; 
} 

[self setupSegmentedControl]; 
} 

- (void)setupSegmentedControl { 

// Setup the UISegmentedControl as groups buttons 
segmentedControl = nil; 

segmentedControl = [[UISegmentedControl alloc] initWithItems:btnArray]; 
segmentedControl.tintColor = [UIColor darkGrayColor]; 
segmentedControl.selectedSegmentIndex = 0; 
segmentedControl.autoresizingMask = UIViewAutoresizingFlexibleWidth; 
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; 
segmentedControl.frame = CGRectMake(0, 0, 300, 30); 

// Setup the target and actions for the segmentedControl 
[segmentedControl addTarget:self 
        action:@selector(selectGroup:) 
      forControlEvents:UIControlEventValueChanged]; 

// Add the UISegmentedControl as a UIBarButtonItem subview to the UIToolbar 
UIBarButtonItem *segmentedItem = [[[UIBarButtonItem alloc] initWithCustomView:segmentedControl] autorelease]; 
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; 
NSArray *groupsButtons = [NSArray arrayWithObjects:flexSpace, segmentedItem, flexSpace, nil]; 
[groupsToolbar setItems:groupsButtons]; 

[flexSpace release]; 
} 

- (void)loadChildren { 

// Retrieve a array with dictionaries of children from ServiceGetChildren 
self.childrensArray = [[serviceGetChildren.childrensArray copy] autorelease]; 

// TODO create seperate method - Setup compilation bar values 
int total = [childrensArray count]; 
totalLabel.text = [NSString stringWithFormat:@"%d", total]; 

[theTableView reloadData]; 
} 

// Handles UIControlEventValueChanged for UISegmentedControl, retreives the name and id for a selected group 
- (void)selectGroup:(UISegmentedControl *)theSegmentedControl { 

NSString *selectedGroup = [segmentedControl titleForSegmentAtIndex: [segmentedControl selectedSegmentIndex]]; 

NSNumber *selectedId = [selectRequestDictionary objectForKey:selectedGroup]; 

// Persist the selectedSegmentIndex when view switches to detaildView 
index = [segmentedControl selectedSegmentIndex]; 

// Request children based on the selected groupId 
[self requestChildren:selectedId]; 
} 

- (void)viewDidLoad { 

[self requestGroups]; 

[super viewDidLoad]; 

// Uncomment the following line to display an Edit button in the navigation bar for this view controller. 
//self.navigationItem.rightBarButtonItem = self.editButtonItem; 
} 

#pragma mark - 
#pragma mark Table view data source 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
// Return the number of rows in the section. 

return [childrensArray count]; 
} 

// Customize the appearance of table view cells. 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

static NSString *CellIdentifier = @"CustomCell"; 

// Load from nib 
CustomCellViewController *cell = (CustomCellViewController *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
if (cell == nil) { 
    NSArray *topLevelObjects = [[NSBundle mainBundle] 
           loadNibNamed:@"CustomCellView" 
           owner:nil 
           options:nil]; 

    for (id currentObject in topLevelObjects) { 
     if ([currentObject isKindOfClass:[UITableViewCell class]]) { 
      cell = (CustomCellViewController *) currentObject; 
      break; 
     } 
    } 
} 
// Set up a children dictionary for easy retrieving specific values to display in the UITableView 
childrensDictionary = [childrensArray objectAtIndex:indexPath.row]; 

NSNumber *idForName = [childrensDictionary valueForKey:@"GroupId"]; 

NSString *name = [NSString stringWithFormat:@"%@ %@", 
           [childrensDictionary valueForKey:@"Firstname"], 
           [childrensDictionary valueForKey:@"Surname"]]; 

NSString *group = [NSString stringWithFormat:@"%@", 
        [selectNameDictionary objectForKey:idForName]]; 

cell.childNameLabel.text = name;  
cell.groupNameLabel.text = group; 
cell.scheduleLabel.text = @"Schema"; 
cell.deviationLabel.text = @"Avvikelse"; 

return cell; 
} 

#pragma mark - 
#pragma mark Table view delegate 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
// Navigation logic may go here. Create and push the detailedViewController. 

if (detailViewController == nil) { 
    DetailViewController *_detailViewcontroller = [[DetailViewController alloc] 
                     initWithNibName:@"DetailView" bundle:nil]; 
    self.detailViewController = _detailViewcontroller; 
    [_detailViewcontroller release]; 
} 
childrensDictionary = [childrensArray objectAtIndex:indexPath.row]; 

NSNumber *idForName = [childrensDictionary valueForKey:@"GroupId"]; 

NSString *group = [NSString stringWithFormat:@"%@", 
        [selectNameDictionary objectForKey:idForName]]; 

[self.detailViewController initWithDetailsSelected:childrensDictionary:group]; 

[self.navigationController pushViewController:detailViewController animated:YES]; 
} 

#pragma mark - 
#pragma mark Memory management 

- (void)didReceiveMemoryWarning { 
// Releases the view if it doesn't have a superview. 
[super didReceiveMemoryWarning]; 

// Relinquish ownership any cached data, images, etc. that aren't in use. 
} 

- (void)viewDidUnload { 
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand. 
// For example: self.myOutlet = nil; 
segmentedControl = nil; 
} 


- (void)dealloc { 

[segmentedControl release]; 
[groupsArray release]; 
[childrensArray release]; 
[detailViewController release]; 

[super dealloc]; 
} 


@end 
+0

[Enable NSZombie](http://cocoa-nut.de/?p=16)爲您的活動可執行文件,並查看控制檯輸出是否顯示新內容。嘗試再次獲取EXC_BAD_ACCESS。 – 2011-05-12 09:28:18

+0

我無法從分配工具發佈圖片,但是每次我推送SegmentedItem時,13個類別都會增加1mb。 – Silversnail 2011-05-12 09:46:19

+0

好的,我們有一個線索。我認爲你應該發佈你創建你的連接的代碼和setLength:發送的部分。 – 2011-05-12 09:52:51

回答

4

OK這裏我們去。首先,我無法測試代碼,所以我需要您的反饋。

這個類的主要問題是,你只有一個實例,每次碰到分段控件時都要重用。這導致創建NSURLConnection的新實例。所以讓我們在頭文件中糾正一下。我改變了NSString屬性來複制。看看this Q&A知道爲什麼,然而這對改善並不重要,只是想讓你知道。

  • 我已刪除Authentication *authentication;看起來像你不使用它。
  • 添加NSURLConnection作爲屬性,所以我們保留對它的引用。

頭文件

@class Authentication; 
@class AttendanceReportViewController; 

@interface ServiceGetChildren : NSObject { 

    AttendanceReportViewController *attendanceReportViewController; 

    NSString *username; 
    NSString *password; 
    NSMutableString *authenticationString; 
    NSString *encodedLoginData; 
    NSMutableData *responseData; 
    NSMutableArray *childrensArray; 
    NSURLConnection *connection; 
} 

@property (nonatomic, copy) NSString *username; 
@property (nonatomic, copy) NSString *password; 
@property (nonatomic, retain) NSMutableString *authenticationString; 
@property (nonatomic, copy) NSString *encodedLoginData; 
@property (nonatomic, retain) NSMutableData *responseData; 
@property (nonatomic, retain) NSMutableArray *childrensArray; 
@property (nonatomic, retain) NSURLConnection *connection 

- (void)startService:(NSURL *)url :(NSString *)method withParent:(UIViewController *)controller; 

@end 

接下來是執行文件。我只改變了startService方法和dealloc。

  • 如果您聲明屬性,請使用它們:)有關合成屬性的一些解釋,請看this Q&A
  • 總是發佈你自己的東西,所以我在dealloc中添加了發佈代碼。
  • 取消上一個請求!!!如果沒有,則該消息被髮送到零,這不會造成傷害。

實現文件

- (void)startService:(NSURL *)url:(NSString *)method withParent:(UIViewController *)controller 
{ 
    self.username = appDelegate.username; 
    self.password = appDelegate.password; 

    [connection cancel]; 

    attendanceReportViewController = (AttendanceReportViewController *)controller; 

    Authentication *auth = [[Authentication alloc] init]; 
    authenticationString = (NSMutableString *)[@"" stringByAppendingFormat:@"%@:%@", username, password]; 
    self.encodedLoginData = [auth encodedAuthentication:authenticationString]; 
    [auth release]; 

    // Setup up the request with the url 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url 
            cachePolicy:NSURLRequestReloadIgnoringCacheData 
           timeoutInterval:20.0]; 
    [request setHTTPMethod:method]; 
    [request setValue:[NSString stringWithFormat:@"Basic %@", encodedLoginData] forHTTPHeaderField:@"Authorization"]; 

    self.connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self] autorelease]; 

    // Display the network indicator when the connection request started 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 

    // Check that the NSURLConnection was successful and then initialize the responseData 
    if (connection) { 
     NSLog(@"Connection made"); 
     self.responseData = [NSMutableData data]; 
    } else { 
     NSLog(@"Connection could not be made"); 
    } 
} 

... 

- (void) dealloc 
{ 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

    [connection cancel]; 
    [connection release]; 

    [appDelegate release]; 
    [responseData release]; 
    [username release]; 
    [password release]; 
    [authenticationString release]; 
    [encodedLoginData release]; 
    [responseData release]; 
    [childrensArray release]; 

    [super dealloc]; 
} 

希望這有助於爲下一個步驟。不過,我認爲我們必須在解決方案上進行一點努力,直到最終。

+0

@尼克,非常感謝!我無法讓它崩潰了!我無法感謝你花時間幫助我! – Silversnail 2011-05-12 16:03:24

+0

我仍然認爲還有一些其他性能問題留給我研究,當我運行分配工具時,我發現每次我推入segmentedItem:Malloc 1.00kb,Malloc 4.0kb,Malloc 8.0kb,Malloc 2.00kb,Malloc 6.00kb,Malloc 96bytes,Malloc 5.50kb,CFString,CFString(存儲),CGColorTransform,CGColorTransFormCache,每增加一次點擊,從1.19mb到4.36mb。 Wich將整個分配的字節相當快地提升到46mb。 – Silversnail 2011-05-12 16:08:06

+0

所以我想我有更多的內存管理來研究。我不知道它可能是什麼。但是這次可能是在ViewController中。 – Silversnail 2011-05-12 16:09:03