调试器消息
我使用 UISegmentedControl
进行 Web 服务请求,当我更改 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 公众涵盖 许可证,欢迎您更改 它和/或分发它的副本 在某些条件下。输入“显示 复制”来查看条件。有 对GDB绝对没有任何保证。 输入“显示保修”以了解详细信息。这 GDB配置为 “--host=i386-apple-darwin --target=arm-apple-darwin".tty /dev/ttys001 将程序加载到 调试器...程序已加载。目标 远程移动 /tmp/.XcodeGDBRemote-239-58 切换 到远程-macosx 协议 mem 0x1000 0x3ffffffff 缓存内存 0x40000000 0xffffffff 无内存 0x00000000 0x0fff none run 正在运行... [切换到线程 11779][切换到线程11779] 共享库应用加载规则全部 继续 程序收到信号: “信号杀死”。警告:无法读取 符号为 /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
I do webservice requests with a UISegmentedControl
, when I change segmentedItem
and request fast the application crashes with this message:
[Session started at 2011-05-12
10:58:50 +0200.] Terminating in
response to SpringBoard's termination.[Session started at 2011-05-12
11:06:31 +0200.] GNU gdb
6.3.50-20050815 (Apple version gdb-1516) (Fri Feb 11 06:19:43 UTC
2011) Copyright 2004 Free Software
Foundation, Inc. GDB is free software,
covered by the GNU General Public
License, and you are welcome to change
it and/or distribute copies of it
under certain conditions. Type "show
copying" to see the conditions. There
is absolutely no warranty for GDB.
Type "show warranty" for details. This
GDB was configured as
"--host=i386-apple-darwin
--target=arm-apple-darwin".tty /dev/ttys001 Loading program into
debugger… Program loaded. target
remote-mobile
/tmp/.XcodeGDBRemote-239-58 Switching
to remote-macosx protocol mem 0x1000
0x3fffffff cache mem 0x40000000
0xffffffff none mem 0x00000000 0x0fff
none run Running… [Switching to thread
11779] [Switching to thread 11779]
sharedlibrary apply-load-rules all
continue Program received signal:
“SIGKILL”. warning: Unable to read
symbols for
/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.3
(8J2)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib
(file not found). kill quitThe Debugger has exited with status
0.(gdb)
Does anybody have an idea of how can I fix this?
Is this a problem because I'm not using NSOperationQueue
?
And if so any suggestions how I can fix this would be very welcomed.
I can not find any memory leaks when running.
Next time I ran it this message got logged:
Program received signal: “EXC_BAD_ACCESS”.
warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.3.3 (8J2)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).
(gdb)
Here is the code for starting the connection:
Class header 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
Class handling the request:
#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];
}
Class header for 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
Class that the Uses the 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好的,我们开始吧。首先,我无法测试代码,所以我需要您的反馈。
此类的主要问题是,您只有一个实例,每次点击分段控件时都会重复使用该实例。这会导致创建 NSURLConnection 的新实例。因此,让我们在标题中修正一下。我将 NSString 属性更改为复制。查看此问答了解原因,但这对于改进,只是想让你知道。
Authentication *authentication;
看起来您没有使用它。头文件
接下来是实现文件。我只改变了startService方法和dealloc。
实施文件
希望这对后续步骤有所帮助。不过,我认为我们必须在解决方案上做一些工作,直到最终确定。
OK here we go. First of all, I could not test the code, so I need your feedback.
The main problem with this class is, you only have one instance, which you reuse every time you hit the segmented control. This leads to creation of new instances of the NSURLConnection. So let's correct a bit in the header. I changed the NSString properties to copy. Have a look at this Q&A to know why, however this is not important for the improvement, just wanted to let you know.
Authentication *authentication;
looked like you don't use it.Header file
Next comes the Implementation file. I only altered the startService method and dealloc.
Implementation file
Hope this helps for the next steps. However I think we will have to work a bit on the solution until it's final.