I am fairly new to Objective-C and iOS programming, and I am having lots of trouble passing data around. I have created a model “LevelsCompleted” where I have declared an NSString property:
@property (readwrite,copy) NSString *answersString;
I synthesized it in the .m file:
@synthesize answersString = _answersString;
Now if I change its value in one of my controllers
-(void) changeAnswersString{
LevelsCompleted *lvls = [[LevelsCompleted alloc] init];
[lvls setAnswersString:@"1"];
}
And then access it from a third controller:
-(void) showAnswerStringValue{
LevelsCompleted *lvls = [[LevelsCompleted alloc]init];
NSLog(@"%@", [lvls answersString]);
}
The console prints null instead of 1
I really can’t find a way to change data for every controller, and my english is very limited so I don’t know what to search for in documentation. Any help please?
Actual Code
// PuzzleOneViewController.m
#import "PuzzleOneViewController.h"
#import "LevelChooseViewController.h"
@interface PuzzleOneViewController(){
int thinInt;
int i;
int answer[10];
bool validSubmit, miniPresent, toDelete;
}
@end
@implementation PuzzleOneViewController
@synthesize levels;
- (IBAction)backButton:(id)sender {
if (levels ==nil) self.levels = [[LevelsCompleted alloc]init];
self.levels.answersString=@"Hello";
[self dismissModalViewControllerAnimated:NO];
}
@end
// PuzzleOneViewController.h
#import <UIKit/UIKit.h>
#import "LevelsCompleted.h"
@interface PuzzleOneViewController : UIViewController{
BOOL grosseur;
NSString *choice;
IBOutlet UIScrollView *sv;
IBOutlet UILabel *cluesLabel;
IBOutlet UILabel *hintLabelText;
}
@property (nonatomic, retain) LevelsCompleted *levels;
- (IBAction)backButton:(id)sender;
@end
// LevelsCompleted.h THIS IS MY MODEL
#import <Foundation/Foundation.h>
@interface LevelsCompleted : NSObject
{
int hello;
BOOL success[30];
NSString *answersString;
}
@property (readwrite,copy) NSString *answersString;
-(BOOL) success:(int)number;
-(void) setSuccess:(BOOL)result atIndex:(int)number;
@end
// LevelsCompleted.m
#import "LevelsCompleted.h"
@implementation LevelsCompleted
@synthesize answersString;
-(BOOL) success:(int)number{
return success[number];
}
-(void) setSuccess:(BOOL)result atIndex:(int)number{
success[number] = result;
}
@end
// LevelChooseViewController.m
#import "LevelChooseViewController.h"
#import "LevelsCompleted.h"
#import "PuzzleOneViewController.h"
@implementation LevelChooseViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(void) viewWillAppear:(BOOL)animated{
PuzzleOneViewController *controller = [[PuzzleOneViewController alloc]init];
NSLog(@"%@",controller.levels.answersString); // prints NULL
NSLog(@"%@", PuzzleOneViewController.levels.answersString); // Generates Error
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([[segue identifier] isEqualToString:@"PassLevelA"]){
[[segue destinationViewController] setChoice:_levelChoice];
}
}
- (IBAction)Level1Choose:(id)sender {
_levelChoice = [[sender currentTitle]intValue];
[self performSegueWithIdentifier:@"PassLevelA" sender:self];
}
@end
And nothing interesting in the LevelChooseViewController.h file…
I could not copy everything because my controllers have 500+ lines of code each, but I but everything relevant (i hope so…) Thanks a lot for helping
You’re not accessing the same LevelsCompleted object instance.
[[LevelsCompleted alloc] init]creates a new LevelsCompleted instance. This is a separate object from the LevelsCompleted object you created in your changeAnswersString method. In order to access that levels completed object from the “third controller”, you need to come up with a way to share data between the two controllers. Without knowing the overall structure of your program, it’s hard to say exactly what you should do, but one easy option is to add a “levels” @property to your first controller, or maybe your application delegate, that way you can access it from other places:In your FirstController.h:
In your FirstController.m:
Then, in changeAnswersString:
Now, in showAnswerStringValue:
As always, you should think carefully about the structure of your program. It’s impossible to convey all the things to consider in a short answer like this one, but I’d recommend reading up on standard Cocoa design patterns, particularly Model View Controller (MVC) paradigm.