调试器消息

时间:2011-05-12 09:17:15

标签: iphone objective-c network-programming

我使用UISegmentedControl进行网络服务请求,当我更改segmentedItem并快速请求应用程序崩溃时显示此消息:

  

[会议于2011-05-12开始   10:58:50 +0200。]终止于   回应SpringBoard的终止。

     

[会议于2011-05-12开始   11:06:31 +0200。] GNU gdb   6.3.50-20050815(Apple版gdb-1516)(星期五2月11日06:19:43 UTC   2011)版权所有2004自由软件   Foundation,Inc。GDB是免费软件,   由GNU General Public提供   许可证,欢迎您进行更改   它和/或分发它的副本   在一定条件下。输入“显示   复制“看看条件。那里   GDB完全没有保修。   输入“show warranty”了解详情。这个   GDB配置为   “主机= I386-苹果达尔文   --target = arm-apple-darwin“.tty / dev / ttys001将程序加载到   debugger ...程序已加载。目标   远程移动   /tmp/.XcodeGDBRemote-239-58切换   到remote-macosx协议mem 0x1000   0x3fffffff缓存mem 0x40000000   0xffffffff无mem 0x00000000 0x0fff   无运行正在运行... [切换到线程   11779] [切换到主题11779]   sharedlibrary apply-load-rules all   继续收到信号:   “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)/Symbols/Developer/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

1 个答案:

答案 0 :(得分:4)

好的,我们走了。首先,我无法测试代码,所以我需要你的反馈。

这个类的主要问题是,你只有一个实例,每次你点击分段控件时都会重复使用它。这导致创建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中添加了发布代码。
  • 取消之前的请求!!!如果没有,则将消息发送给nil,这不会造成任何伤害。

实施文件

- (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];
}

希望这有助于后续步骤。但是我认为我们将不得不对解决方案进行一些研究,直到它最终为止。