ABPeoplePickerNavigationController crashes in IOS 7 - iphone

I have problem with ABPeoplePickerNavigationController in IOS 7 with the following error
*** -[ABPeoplePickerNavigationController respondsToSelector:]: message sent to deallocated instance 0x9b4b050
on IOS 6 it is working fine but in ios 7 it gives this error with zombies enabled without zombies it was like
Thread 1: EXC_BAD_ACCESS(code=2,address=0x0)
than i enable zombies
here is my code
- (void)viewDidLoad
{
[super viewDidLoad];
self.contacts = [[NSMutableArray alloc] initWithCapacity:10];
self.addressBook=ABAddressBookCreateWithOptions(NULL, NULL);
[self checkAddressBookAccess];
}
(void)requestAddressBookAccess
{
ContactsViewController * __weak weakSelf = self;
ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error)
{
if (granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf accessGrantedForAddressBook];
});
}
});
}
-(void)accessGrantedForAddressBook
{
NSMutableArray *savedContacts=[[NSMutableArray alloc] initWithArray:[DatabaseHandler getAllContacts]];
if (savedContacts &&savedContacts.count!=0)
[self.contacts addObjectsFromArray:savedContacts];
}
- (IBAction)popUpAddExistingContact:(id)sender {
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[picker setDelegate:self];
[self presentViewController:picker animated:YES completion:nil];
}
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated{
NSString *viewControllerDesc=[viewController description];
NSString *t_st = #"ABContactViewController";
NSRange rang =[viewControllerDesc rangeOfString:t_st options:NSCaseInsensitiveSearch];
if (rang.length == [t_st length])
{
navigationController.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(addPerson:)];
}
else if([navigationController isKindOfClass:[ABPeoplePickerNavigationController class]] && [viewController isKindOfClass:[ABPersonViewController class]])
{
ABPersonViewController *DVC=(ABPersonViewController*)viewController;
self.currentPerson=DVC.displayedPerson;
navigationController.topViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(addPerson:)];
}
else{
navigationController.topViewController.navigationItem.rightBarButtonItem = nil;
}
navigationController.topViewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancel:)];
}
-(IBAction)addPerson:(id)sender{
if (self.currentPerson!=NULL)
{
CFStringRef firstName;
int recordID;
firstName = ABRecordCopyValue(self.currentPerson, kABPersonFirstNameProperty);
recordID = ABRecordGetRecordID(self.currentPerson);
MyContact *contact=[[MyContact alloc] init];
contact.Name=(__bridge NSString *)(firstName);
contact.contactID=[NSString stringWithFormat:#"%i",recordID];
contact.phones=[[NSMutableArray alloc] init];
ABMultiValueRef phones = ABRecordCopyValue(self.currentPerson, kABPersonPhoneProperty);
for(CFIndex j = 0; j < ABMultiValueGetCount(phones); j++)
{
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(phones, j);
CFStringRef locLabel = ABMultiValueCopyLabelAtIndex(phones, j);
NSString *phoneNumber = (__bridge NSString *)phoneNumberRef;
[contact.phones addObject:phoneNumber];
CFRelease(phoneNumberRef);
CFRelease(locLabel);
}
CFRelease(firstName);
//CFRelease(lastName);
}
//[self dismissModalViewControllerAnimated:YES];
[self dismissViewControllerAnimated:YES completion:^(void ){
[self.popUpContactView removeFromSuperview];
}];
}
as soon as peoplepickercontroller is dismissed app crashed in ios 7
*** -[ABPeoplePickerNavigationController respondsToSelector:]: message sent to deallocated instance 0xb236c00
0x17d811: jmp 0x17d90c ; ___forwarding___ + 1020
Thread 1:EXC_BREAKPOINT (code=EXC_1386_BPT,sucode 0x0)

try to set peopleViewController delegates to nil before dismissing and disable second possible call of this action during some time (like if user pressed button several times). Assume you have a reference to ABPeoplePickerNavigationController instance. Something name like self.adressBook;
Then before dismissing PeoplePickerNavigationController set
self.adressBook.peoplePickerDelegate = nil
self.adressBook.delegate = nil;
and make sure that you do not call your peoplePickerNavigationController reference after dismissing or your reference to this instance is of weak, not assign type.

- (IBAction)popUpAddExistingContact:(id)sender {
ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
picker.peoplePickerDelegate = self;
[picker setDelegate:self];
[self presentViewController:picker animated:YES completion:nil];
}
I think it is because the view controller created is not retained,
Call [self addChildViewController:picker] or else maintain a "strong" reference for it

Related

game center unavailable player is not signed in

On iOS 6 when a player is not signed in and is trying to use GameCenter an UIAlertView with the text that i put in title pops up. "game center unavailable player is not signed in". My question is is it possible to replace that UIAlertView with anything else, with my own interface element?
[GKLocalPlayer localPlayer].authenticateHandler = ^(UIViewController *viewController, NSError *error)
{
if ([[GKLocalPlayer localPlayer] isAuthenticated])
{
NSLog(#"[gamecenter] player authenticated: %#\n", [GKLocalPlayer localPlayer]);
[self gamecenterLoadAchievements];
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite)
{
// Insert application-specific code here to clean up any games in progress.
if (acceptedInvite)
{
NSLog(#"Accepted invitation");
isInvited = YES;
[[GameLevel sharedGameLevel] setCurrentGameMode:GameModeGameCenter];
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
mmvc.matchmakerDelegate = self;
AppDelegate * delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
[delegate.viewController presentModalViewController:mmvc animated:YES];
}
else if (playersToInvite)
{
NSLog(#"Players to invite");
GKMatchRequest *request = [[[GKMatchRequest alloc] init] autorelease];
request.minPlayers = 2;
request.maxPlayers = 2;
request.playersToInvite = playersToInvite;
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithMatchRequest:request] autorelease];
mmvc.matchmakerDelegate = self;
[presentingViewController presentModalViewController:mmvc animated:YES];
}
};
}
else
if (viewController)
{
AppDelegate *delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
NavigationController *_viewController = delegate.viewController.navController;
[_viewController presentViewController: viewController animated: YES completion:nil];
}
else
{
NSLog(#"[gamecenter] %#\n", error);
gcLoginFailed = YES;
if ([[error domain] isEqualToString:GKErrorDomain])
{
if ([error code] == GKErrorNotSupported)
gcIsSupported = NO;
else
if ([error code] == GKErrorCancelled)
gcLoginCancelled = YES;
}
}
};
Just not use UIAlertView Use your own graphics with a UIButton
If you are using the disableGameCenter method in authenticating , just don't use it , instead of it use a integer ilk int isPlayerSignedIn . And just return it to 1 or 0 . So ;
if (isPlayerSignedIn==0) {
//display your graphics
}
else do nothing .
edit :
else
if (viewController)
{
AppDelegate *delegate = (AppDelegate *) [UIApplication sharedApplication].delegate;
NavigationController *_viewController = delegate.viewController.navController;
[_viewController presentViewController: viewController animated: YES completion:nil];
}
just if you don't use these lines of code you will see that you don't get that UIAlertView
Then you can implement a "game center is unavailable" staff , but additionally you have to implement a login screen too.

Memory-management in iOS Programming

I have a little problem with memory management in my iOS App. I load an XML and set all Values in this XML to Spezific Objects. Now my problem is when i reload the XML every 15 - 20 reloads of this XML my app Crash on Parsing here is a sample of my parser.
EDIT: Here ist the ERROR when NSZombie is Enabled if NSZombie is disabled I didn't get an ERROR message.
-[CFNumber retain]: message sent to deallocated instance
thanks for help.
EDIT:
the beginning of my Code:
- (id)init
{
self = [super init];
if (self) {
TheObjects *theObjects = [[TheObjects alloc] init];
[self parse];
}
return self;
}
- (void) reload{
reload = YES;
TheObjects *theTmpObjects = [[TheObjects alloc] init];
[self parse];
}
- (void)parse{
for (id xmlOBject in xmlObjects){
MyObject *object = [[MyObject alloc] init];
object.number1 = [NSNumber numberWithInt:1];
object.number2 = [NSNumber numberWithInt:2];
object.number3 = [NSNumber numberWithInt:3];
if (reload)
[theTmpObjects.objects addObject:object];
else
[theObjects.objects addObject:object];
[object release];
}
//later in my code
TheObjects *localTheTmpObjects = nil;
if (reload){
localTheTmpObjects = theObjects;
theObjects = theTmpObjects;
}
if ([delegate respondsToSelector:#selector(finished:)]){
[delegate performSelector:#selector(finished:) withObject:theObjects];
}
if(reload)
[localTheTmpObjects release];
}
remove the line [localTheTmpObjects release]
you don't own the object
at the end, call the `[localTheTmpObjects autorelease];`
this is because if you release array, all its objects are released and hence may cause crash, when your array may in use
- (id)init
{
self = [super init];
if (self) {
TheObjects *obbjects = [[TheObjects alloc] init];
theObjects = objects;
[objects releas];
[self parse];
}
return self;
}
- (void) reload{
reload = YES;
TheObjects *obbjects = [[TheObjects alloc] init];
thetmpObjects = objects;
[objects releas]; [self parse];
}
- (void)parse{
for (id xmlOBject in xmlObjects){
MyObject *object = [[MyObject alloc] init];
object.number1 = [NSNumber numberWithInt:1];
object.number2 = [NSNumber numberWithInt:2];
object.number3 = [NSNumber numberWithInt:3];
if (reload)
[theTmpObjects.objects addObject:object];
else
[theObjects.objects addObject:object];
[object release];
}
//later in my code
TheObjects *localTheTmpObjects = nil;
if (reload){
localTheTmpObjects = theObjects;
theObjects = theTmpObjects;
}
if ([delegate respondsToSelector:#selector(finished:)]){
[delegate performSelector:#selector(finished:) withObject:theObjects];
}
}

MFMessageComposeViewController dismiss keyboard

i'm having troubles with my MFMessageComposeViewController. I would like to use SMS in-app.
Everything work fine for sending SMS, so far so good. But when i hit the cancel button (or send button too) top of my view disapeared but the keyboard did not. It's maybe because i don't use modale view, but only a addSubview.
-(void)messageComposeViewController:(MFMessageComposeViewController *)controller didFinishWithResult:(MessageComposeResult)result
{
if (result == MessageComposeResultCancelled)
{
NSLog(#"Message annulé");
[controller resignFirstResponder];
[controller.view removeFromSuperview];
[controller release];
}
else if (result == MessageComposeResultSent)
{
NSLog(#"Message envoyé");
...
}
else
{
NSLog(#"Message non envoyé");
...
}
}
-(void)sendSMS:(NSString *)bodyOfMessage :(Phone *)recipient
{
MFMessageComposeViewController *controller = [[MFMessageComposeViewController alloc] init];
if([MFMessageComposeViewController canSendText])
{
MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
picker.messageComposeDelegate = self;
NSMutableArray *toRecipients = [[NSMutableArray alloc]init];
[toRecipients addObject:recipients.phoneNumber];
[picker setRecipients:(NSArray *)toRecipients];
[toRecipients release];
NSString *bodyString = nil;
bodyString = bodyOfMessage;
[picker setBody:bodyString];
[self addSubView:picker.view];
[picker release];
}
}
Any idea ? Had I to use only modalView ?
sorry for spelling mistake...
Thank you. Tommy
Yes, you have to use the modalviewcontroller.
[self presentModalViewController:picker];
Also, you're creating two instances of the MFMessageComposeViewController, first for checking if it can send text and then another to actually show it. I advise to create just one, it's better for the memory :) also the first one is leaking since you didn't release it. Good luck!
if ([MFMessageComposeViewController canSendText]) {
MFMessageComposeViewController *picker = [[MFMessageComposeViewController alloc] init];
picker.messageComposeDelegate = self;
NSString *bodyString = nil;
NSMutableArray *toRecipients = [[NSMutableArray alloc]init];
[toRecipients addObject:#"phone here"];
[picker setRecipients:(NSArray *)toRecipients];
[toRecipients release];
bodyString = [NSString stringWithFormat: #"Message body"];
[picker setBody:bodyString];
[self presentModalViewController:picker animated:YES];
[picker release];
}
Try close existing keyboard, before presenting modal view controller with MFMessageComposeViewController:
[self.view endEditing:YES]; //close keyboard if it opened
[self presentModalViewController:messageController animated:YES];

iPhone -trouble with a loading data from webservice into a tableview

I am using a Window based application and then loading up my initial navigationview based controller in the appDelegate part - application didFinishLaunchingwithOptions (UPDATED)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
The method of getting the data from the webservice is usually triggered in this method of viewdidload .... in the [self getData]; method.
- (void)viewDidLoad
{
[super viewDidLoad];
if (_refreshHeaderView == nil) {
EGORefreshTableHeaderView *view = [[EGORefreshTableHeaderView alloc] initWithFrame:CGRectMake(0.0f, 0.0f - self.tableView.bounds.size.height, self.view.frame.size.width, self.tableView.bounds.size.height)];
view.delegate = self;
[self.tableView addSubview:view];
_refreshHeaderView = view;
[view release];
}
// update the last update date
[_refreshHeaderView refreshLastUpdatedDate];
[self loadImages];
HUDMB = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUDMB];
HUDMB.dimBackground = YES;
// Regiser for HUD callbacks so we can remove it from the window at the right time
HUDMB.delegate = self;
HUDMB.labelText = #"Loading..";
[HUDMB show:TRUE];
[self getData];
[self.tableView reloadData];
}
Before loading it if the user is not registered/ does not have a credentials present then it takes the user to a login view controller .
- (void)loadView {
[super loadView];
if([Preferences isValid]?YES:NO)
{
}
else
{
int r = arc4random() % 5;
switch (r) {
case 0:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 1:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 2:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 4:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStylePartialCurl];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
case 3:
{
loginViewController *sampleView = [[loginViewController alloc] initWithNibName:#"loginViewController" bundle:nil];
[sampleView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
[self.navigationController presentModalViewController:sampleView animated:YES];
[sampleView release];
}
break;
default:
break;
}
}
}
I think the getdata function is making a lot of troubles. so let me add that and also the corresponding functions i use for data retrieval and serialization.
-(void)getData{
NSLog(#"loggin into call sheet page");
[self getCallSheetData];
NSLog(#"after call sheet");
}
- (void)getCallSheetData
{
NSString *postCMD = #"Blah... Blah... Blah...";
NSMutableData *postDataCMD = (NSMutableData *)[postCMD dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSURL *url = [NSURL URLWithString:[Preferences getURL]];
// NSLog(#"get call Sheet");
NSString *postLengthCMD = [NSString stringWithFormat:#"%d", [postDataCMD length]+1];
// NSLog(#"The CS String: %#",[Preferences retriveSession]);
requestCMD = [ASIHTTPRequest requestWithURL:url];
[requestCMD setURL:url];
[requestCMD addRequestHeader:#"Content-Length" value:postLengthCMD];
[requestCMD addRequestHeader:#"Content-Type" value:#"application/x-www-form-urlencoded"];
[requestCMD addRequestHeader:#"user-Agent" value:#"Mobile 1.4" ];
[requestCMD addRequestHeader:#"Content-Language" value:#"en-US"];
[requestCMD addRequestHeader:#"Accept-Encoding" value:#"gzip"];
[requestCMD addRequestHeader:#"Cookie" value:[Preferences retriveSession]];
[requestCMD setPostBody:postDataCMD];
[requestCMD setDelegate:self];
[requestCMD startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSMutableArray *CSArray = [[NSMutableArray alloc] init];
if( [[request responseString] isEqualToString:#"OK"]){
return;
}
// Use when fetching binary data
NSData *responseData = [request responseData];
NSDateFormatter *formatter1=[[NSDateFormatter alloc]init];
[formatter1 setDateFormat:#"yyyy-MM-dd'T'HH:mm:ss'Z'"];
NSTimeZone *gmt = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
[formatter1 setTimeZone:gmt];
NSDateFormatter *formatterFinal=[[NSDateFormatter alloc]init];
[formatterFinal setDateStyle:NSDateFormatterMediumStyle];
[formatterFinal setTimeStyle: NSDateFormatterShortStyle];
[formatterFinal setLocale:[NSLocale currentLocale]];
JSONDecoder *jCSArray = [[JSONDecoder alloc]init];
NSMutableArray *theObject = [jCSArray objectWithData:responseData];
// CallSheet= [NSMutableArray arrayWithCapacity:50];
for(id key in theObject)
{
csr = [[CallSheetRecord alloc] init];
// cName,cCompany,cId,cMemberId,crcStatus,crcTarget,cImportance,cLastContact
csr.importance = #"1";
csr.rcstatus = #"1";
csr.rcTarget = #"1";
csr.company = #"";
csr.lastContact= #"";
if([key valueForKey:#"firstName"] != Nil)
{
csr.name = [NSString stringWithFormat:#"%#",[key valueForKey:#"firstName"]] ;
if ([key valueForKey:#"lastName"] != Nil) {
csr.name = [csr.name stringByAppendingString:#" "];
csr.name = [csr.name stringByAppendingString:[NSString stringWithFormat:#"%#",[key valueForKey:#"lastName"]]];
}
}
if([key valueForKey:#"company"] != Nil)
{
csr.company = [NSString stringWithFormat:#"%#",[key valueForKey:#"company"]] ;
}
if([key valueForKey:#"memberId"] != Nil)
{
csr.memberId = [NSString stringWithFormat:#"%#",[key valueForKey:#"memberId"]] ;
}
if([key valueForKey:#"id"] != Nil)
{
csr.id_ = [NSString stringWithFormat:#"%#",[key valueForKey:#"id"]] ;
}
if([key valueForKey:#"lastContact"] != Nil)
{
NSDate *finalDate =[formatter1 dateFromString:[NSString stringWithFormat:#"%#",[key valueForKey:#"lastContact"]]];
//NSString *timeStamp = [formatter1 stringFromDate:[finalDate descriptionWithLocale:[NSLocale currentLocale]]];
//NSLog(#"Time stamp : %#",[finalDate descriptionWithLocale:[NSLocale currentLocale]]);
//NSLog(#"Time stamp : %#",timeStamp);
//csr.lastContact = [key valueForKey:#"lastContact"];
csr.lastContact = [formatterFinal stringFromDate:finalDate];
}
if([key valueForKey:#"importance"] != Nil)
{
csr.importance = [NSString stringWithFormat:#"%#",[key valueForKey:#"importance"]];
}
if([key valueForKey:#"rcStatus"] != Nil)
{
csr.rcstatus= [NSString stringWithFormat:#"%#",[key valueForKey:#"rcStatus"]] ;
}
if([key valueForKey:#"rcTarget"] != Nil)
{
csr.rcTarget = [NSString stringWithFormat:#"%#",[key valueForKey:#"rcTarget"]] ;
}
[CSArray addObject:csr];
}
CSD = [CSArray mutableCopy];
[CSArray release];
[formatter1 release];
[formatterFinal release];
//CallSheetArray = [CSArray mutableCopy];
//[csr release];
[jCSArray release];
[HUDMB hide:TRUE];
[self.tableView reloadData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
UIAlertView *message = [[[UIAlertView alloc] initWithTitle:#"Hello World!"
message:[NSString stringWithFormat:#"%#",error]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil]autorelease];
[message show];
}
then right after that i try to load the table with [self getData]; that i get make using webservice call using asiHTTP .. for this question lets say it takes 3 seconds time to get the data and then deserialize it . now... my question is it works out okey in the later runs as I store the username and password in a seure location... but in the first instance.... i am not able to get the data to laod to the tableview... I have tried a lot of things...
1. Initially the data fetch methods was in a diffrent methods.. so i thought that might be the problem as then moved it the same place as the tbleviewController(navigationController)
2. I event put in the Reload data at the end of the functionality for the data parsing and deserialization... nothing happens.
3. The screen is black screen with nothing displayed on it for a good 5 seconds in the consecutive launches of the app.... so could we have something like a MBPorgressHUD implemented for the same.
could any one please help for these scenarios and guidance as to what paths to take from here. ...
Update:
Bounty Just answer 2 of the questions the best you can... The property was a thing i tried but it did not work... but my problem is not that... my problem is my screen is not able to load data from a webservice after i login until i do the "pull to refresh". Next eventualy starting my app takes about 5 seconds to show the screen(till that it shows a black screen)... what is the best way to show the apps Blank screen to the End- user when they make it to the app. I dont want the user to think the app is not working or has adversly affected their phone.
There are a number of potential issues here. The first is related to [self getData] - is this blocking or not?
1. getData is blocking (synchronous)
If this method is blocking (i.e. does not return immediately) then this will explain why you are not seeing anything on the screen for a few seconds. You are currently calling this method in the main thread, so it will stop the UI from being updated until is complete.
You can make it run in the background by doing this:
- (void) getDataInBackgroundThread
{
NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
[self getData];
// force the table to redraw - UI operations must be on the main thread
[tableView performSelectorOnMainThread:#selector( reloadData )];
[pool drain];
}
In your main code, now instead of calling [self getData] call [self getDataInBackgroundThread];
2. getData is not blocking (asynchronous)
Even if getData is blocking, if it runs in the main thread it will still cause the UI to hang. Also, if it uses a lot of processor time it will slow down the UI and give the appearance of not running in the background.
To address this issue, you would need make sure the lengthy operation of getData really is not running in the main thread and also put in sleep() calls every so often to give some time for the UI to update.
You still haven't given enough info for people to really help, we're just guessing.
It is highly likely the delay is caused by getData. Try commenting that out or bracket it with NSLog statements to verify.
You should show us more code, specifically what is happening in getData and any delegate or notification handling implementations related to loading data.
You don't need to explicitly call [tableView reloadData] in viewDidLoad. The tableView automatically loads data the first time it is displayed.
As #dmatt said, if you are loading data asynchronously then getData would return immediately with no delay. You would typically would either respond to delegate messages or notifications (depending on how you are loading data) to reload the table when the data is finished loading and serializing.
There are lots of folks on SO who are happy to try and help you if given enough info. Especially when you offer a bounty.

init an array in initWithNibName

I am trying to set up an array in my UIViewController. The nib gets loaded into my app, sometimes repeatedly. I am adding this to my initWithNibName to init the array
NSMutableArray *temp = [[NSMutableArray alloc] initWithObjects:#"one",#"two",#"three",#"four",#"five",nil];
[self setScoreArray:temp];
[temp release];
scoreArray is a MutableArray with synthesized properties. When I go to access the array in viewDidLoad I get [[self scoreArray] count] as 0. Also, when I load the nib repeatedly I get a bad access error. Any suggestions? Am I missing a step. Thanks. I am synthesizing the property for the array, in my class declaration:
NSMutableArray *_scoreArray;
then
#property (nonatomic, retain) NSMutableArray *scoreArray;
then in my implementation
#synthesize scoreArray =_scoreArray;
and in my dealloc
[_scoreArray release], _scoreArray = nil;
I'm editing this post to show how I'm loading the nibs with my RootViewController
- (void) createNewSlide:(NSInteger)slideIndex {
NSDictionary *slideObj = (NSDictionary *)[[self slidesDataSource] objectAtIndex:slideIndex - 1];
NSString *currentTitle = [slideObj objectForKey:#"title"];
[[self slideTitle] setText:currentTitle];
NSString *currentContent = [slideObj objectForKey:#"contentString"];
NSString *currentContentType = [slideObj objectForKey:#"contentType"];
if ([self currentVC] != nil) {
[[self currentVC] reset];
[self setCurrentVC:nil];
}
if ([currentContentType isEqualToString:#"slide"])
{
[[self containerViewController] loadImage:currentContent];
}
else if ([currentContentType isEqualToString:#"quiz"])
{
NSInteger quizNum = [[slideObj objectForKey:#"quizNum"] integerValue];
NSLog(#"%s%#%d",__FUNCTION__,#"quizNum ",quizNum);
QuizViewController *quizView = [[QuizViewController alloc] initWithNibName:#"QuizViewController" bundle:nil];
[self setCurrentVC:quizView];
[quizView release];
[[self containerViewController] replaceSlideWithViewController:[self currentVC]];
}
else if ([currentContentType isEqualToString:#"PIDView"])
{
PIDViewController *PIDView = [[PIDViewController alloc] initWithNibName:#"PIDView" bundle:nil];
[self setCurrentVC:PIDView];
[PIDView release];
[[self containerViewController] replaceSlideWithViewController:[self currentVC]];
}
else if ([currentContentType isEqualToString:#"LoginView"])
{
LoginViewController *login = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil];
[self setCurrentVC:login];
[login release];
[[self containerViewController] replaceSlideWithViewController:[self currentVC]];
}
else if ([currentContentType isEqualToString:#"VakView"])
{
VakViewController *vakView = [[VakViewController alloc] initWithNibName:#"VakView" bundle:nil];
[self setCurrentVC:vakView];
[vakView release];
[[self containerViewController] replaceSlideWithViewController:[self currentVC]];
}
else if ([currentContentType isEqualToString:#"PlanView"])
{
PlanViewController *planView = [[PlanViewController alloc] initWithNibName:#"PlanView" bundle:nil];
[self setCurrentVC:planView];
[planView release];
[[self containerViewController] replaceSlideWithViewController:[self currentVC]];
}
Thanks for your insights.
PlanView is the one that causes the problem. But it is not when it loads, it's when something else loads after it. I have run the analyzer and it reports no memory leaks.
BTW, currentVC is a synthesized property.
How is your UIViewController being created? If it is being created via another nib, then -initWithNibName:bundle: doesn't get called. Instead, -initWithCoder: and -awakeFromNib are called.