我使用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
答案 0 :(得分:4)
好的,我们走了。首先,我无法测试代码,所以我需要你的反馈。
这个类的主要问题是,你只有一个实例,每次你点击分段控件时都会重复使用它。这导致创建NSURLConnection的新实例。所以让我们在标题中纠正一下。我更改了要复制的NSString属性。看看this Q&A知道原因,但这对改进并不重要,只是想让你知道。
Authentication *authentication;
看起来你不使用它。 标头文件
@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。
实施文件
- (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];
}
希望这有助于后续步骤。但是我认为我们将不得不对解决方案进行一些研究,直到它最终为止。