2011-05-12 81 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