I've got a class, called Letter. In the init method of Letter I am trying to load an Array of strings, so they can be used by other methods of that class.
I'm then instantiating an object based on the Letter class. I am expecting the init call to load the array, but instead am getting a EXC_BAD_ACCESS error.
Letter.h
#interface Letter : NSObject
{
NSArray *consonants;
}
-(BOOL)typeOfLetter:(NSString *)_letter;
Letter.m
#import "Letter.h"
#implementation Letter
- (id)init {
self = [super init];
if (self) {
consonants = [NSArray arrayWithObjects:#"B",#"C",#"D",#"F",#"G",#"Ğ",#"H",#"J",#"K",#"L",#"M",#"N",#"P",#"R",#"S",#"Ş",#"T","#U",#"V",#"Y",#"Z",#"b",#"c",#"d",#"f",#"g",#"ğ",#"h",#"j",#"k",#"l",#"m",#"n",#"p",#"r",#"s",#"ş",#"t",#"u",#"v",#"z",nil];
}
return self;
}
ViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
BOOL retValue;
Letter *letter = [[Letter alloc] init];
retValue = [letter typeOfLetter:#"a"];
}
What am I doing incorrectly here?
You have forgotten to add a # before one of your strings
In your array you have this character "#U" you will have to change it to #"U"
Related
Greetings i need to init alloc an instance of a class and have it accessible by any method
Example for using "Whatever *boom = [Wathever alloc]init];"
#interface something : NSObject;
#implementation
-(void) method1{
boom.size = 10;
}
-(void) method2{
boom.color = blue;
}
Where would i alloc and init boom so that i can manipulate it in every method?
for example in whatever.h and whatever.m to call the methods of a class must be declared in whatever.h
-(void) method1;
-(void) method2;
and used
Whatever *boom = [Wathever alloc]init];
[boom method1];
[boom method2];
In a single class? Make it a property of that class.
//.h
#property Whatever *boom;
//.m
- (id)init {
self = [super init];
if (self) {
_boom = [[Whatever alloc] init];
}
return self;
}
Across your whole app? Create an instance of it somewhere, like your app delegate, and then pass it along to the Root View Controller, which in turns passes it to each View Controller.
// AppDelegate .m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// app setup code
Whatever *boom = [[Whatever alloc] init];
FirstViewController vc = self.window.rootViewController;
vc.boom = boom;
}
// FirstViewController.h, NextViewController.h, etc.
#property Whatever *boom;
// FirstViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NextViewController *nextVC = sender.destinationViewController;
nextVC.boom = self.boom;
}
You could also go the Singleton route, but then you are tightly coupled to a single instance of the class app-wide.
See when you create a class in that to intialize that class a common method will always be there which calls that class it self:
Something like this :
-(id)init
{
self = [super init];
if (self)
{
}
return self;
}
You can declare the instance in .h file like this :
Whatever *boom;
Than you can initialize that instance in above method as following :
-(id)init
{
self = [super init];
if (self)
{
boom = [Wathever alloc]init];
}
return self;
}
hope this will help you.
So I have two classes. When press the save button, it will pass down the value from self.screen.text by addItem method to the totalArray in class 2. If I try to NSLog in the #implementation of addItem method, then it will give out the correct output but If I do it in viewDidLoad, the output is null. How can I save the value passing from class1 to property of class2 permanently? Thank you. The class2 in a subclass of UITableViewController
Class 1 #interface
//class1.h
#import class2.h
#interface class1 : superclass {
}
- (IBAction)buttonSave:(id)sender;
Class1 #implementation
//class1.m
#interface class1 ()
#end
#implementation class1 {
}
- (IBAction)buttonSave:(id)sender {
class2 *Obj = [[class2 alloc] init];
[Obj addItem:self.screen.text];
}
And class2 #interface
//class2.h
#import class2.h
#interface {
}
#property (strong, nonatomic) NSMutableArray *totalArray;
class2 #implementation
#interface class2 ()
#end
#implementation {
}
- (void) addItem:(id)item {
self.totalArray = [[NSMutableArray alloc] init]; //alloc & init
[self.totalArray addObject:item]; //add object to the total array
// NSLog(#"%#", self.totalArray); If I NSLog in within this method then everything works as expected.
}
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", self.totalArray); //But in here the output is null. ???
}
I think that your problem is that you have use a different class2 object. The one that you had init in buttonSave, is not the one that you are displaying
add a property in class1.h
#property (nonatomic, strong) NSMutableArray *savedArray;
and modify buttonSave :
- (IBAction)buttonSave:(id)sender {
self.savedArray = [[NSMutableArray alloc] init];
[self.savedArray addObject:self.screen.text];
}
You are using a storyboard, then please try to add this in class1.h and add an identifier class2Segue to this segue in your storyboard :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"class2Segue"])
{
Class2 *tableController = (Class2 *)[segue destinationViewController];
tableController.totalArray = self.savedArray;
}
}
viewDidLoad is called after init so you array is nil here. Change your class2 init method to accept the item.
// In class2
-(id) initWithStyle:(UITableViewStyle)style andItem:(id)item {
self = [super initWithStyle:style];
if(self) {
self.totalArray = [[NSMutableArray alloc] init];
[self.totalArray addObject:item];
}
return self;
}
Your addItem will then look like,
- (void) addItem:(id)item {
//Just add, do not initialize again
[self.totalArray addObject:item];
}
The button action in class1 will now look like,
- (IBAction)buttonSave:(id)sender {
class2 *Obj = [[class2 alloc] initWithItem:self.screen.text];
//OR
//class2 *Obj = [[class2 alloc] initWithItem:UITableViewStylePlain andItem:self.screen.text];
}
Hope that helps!
Try to use like this...
- (IBAction)buttonSave:(id)sender
{
class2 *Obj = [[class2 alloc] init];
Obj.totalArray = [[NSMutableArray alloc] init]; //alloc & init
[Obj.totalArray addObject:self.screen.text];
NSLog(#"screen.text %#", self.screen.text); // -- check here it may be null----
NSLog(#"Obj.totalArray %#", Obj.totalArray);
}
#interface class2 ()
#end
#implementation {
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSLog(#"%#", self.totalArray); //But in here the output is null. ???
}
You can not ensure when your viewDidLoad method will call... so better pass the value to the init method and set there initWithText:(NSString*)text{}. Other wise try to call NSLog in viewWillAppear or viewDidAppear just for testing purpose. In iOS 7 now presentation of view-controllers is bit changed now.
I have a method in a NSObject Class that I am executing from another ViewController Class, I would like to reutrn a NSMutableArray however I am not sure how to pass that into a variable in the ViewController class.
Updated Code:
NSObject Class is called Axis
Axis.h
// declare my method here with return type of NSMutableArray
- (NSMutableArray *)assignAxes:(NSArray*)axesData;
Axis.m
- (NSMutableArray *)assignAxes:(NSArray*)axesData {
//..
//pass some NSDictionaries into a MutableArray called myMutableArray
return myMutableArray;
}
Now I have a View Controller called FinalViewViewController and I want to call assignAxes method from this viewController, and I would like to put the returning myMutableArray into a mutableArray variable in FinalViewViewController but am not sure how... I only know how to call the method not pass the returning value into a variable to be used.
FinalViewViewController.m
Axis *axis = [[Axis alloc] init];
NSMutableArray *tempGetSeriesObjArray = [[NSMutableArray alloc] init]; // create holder variable for returning mutableArray
tempGetSeriesObjArray = [axis assignAxes:series]; // gives an error
This is the error I am getting from that last line of code
Incompatible pointer types assigning to 'NSMutableArray *__strong' from 'Axis *'
any help would be appreciated.
In your NSObject Class, first go in your .h file and make the declaration of the array and set the property
#interface YourNSObjectClass : NSObject {
NSMutableArray *_myArray;
}
#property (nonatomic, retain) NSMutableArray *_myArray;
- (NSMutableArray *) getMyArray; // declare method
#end
So now, you have to sync your variable and initialize it in the initMethod - if you have a custom init-method you have to declare it too and make it inside of there.
#synthesize _myArray;
- (id) init {
if(self = [super init]) {
_myArray = [[NSMutableArray alloc] init];
}
return self;
}
And the getter-method should work too
- (NSMutableArray *) getMyArray {
return _myArray;
}
I have two UIViews. One UIView, called SelectText has an ivar of NSMutableArray which is populated after performing a certain function.
Here is a snippet code:
- (void)fillDrawPoints
{
//the codes....
[self.drawnPoints addObject:[NSValue valueWithCGPoint:currPoint]];
}
NOTE: The drawnPoints array is initialized in the initWithFrame of SelectText. Also, I always check if the array is actually populated inside the view by putting a log in the function.
Now what I want to do is to access this array from another view. This is what I do:
TextView.h
#import "SelectText.h"
#interface TextView : UIView
{
SelectText *txtSel;
}
#property (nonatomic, retain) SelectText *txtSel;
TextView.m
#synthesize txtSel;
- (void)getDrawingPoints:(NSMutableArray *)pointArray
{
self.pointArray = pointArray;
NSLog(#"Array count: %d", [self.pointArray count]);
}
As you can see from the above code, I am trying to pass the data inside txtSel.drawnPoints to the textView.pointArray for later use. The problem is, the txtSel.drawnPoints always returns empty when I try to access it from another view. What am I doing wrong here?
ADDITIONAL:
This is how I instatiate SelectText
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
txtSel = [[SelectText alloc]init];
[self addSubView:txtSel];
//rest of code...
}
change TextView class init method as below
- (id)initWithClassSelectText:(SelectText *)selectText {
if ((self = [super init])) {
txtSel = selectText;
}
return self;
}
And when you make an instance of TextView you use this:
TextView textView = [[TextView alloc] initWithClassSelectText:self];
now you can access all properties of SelectText class using txtSel object
I want to load data (an array of strings) from the parent view into a set of UITextFields in the child view upon presenting the modalView.
I know how to pass from child to parent, and I'm sure it's even easier to go the other way, but I don't know how.
UPDATE: Update removed because I found the problem (double releasing of modal view)
Override the init method for the child view controller.
- (id) initWithStrings:(NSArray *)string {
if (self = [super init]) {
// Do stuff....
}
return self;
}
Then in the parent:
MyChildViewController *vc = [[[MyChildViewController alloc] initWithStrings: strings] autorelease];
Two ways you could do it:
1.Override the init method as Matt suggests
2.Create fields in your child class and pass those values to your text field.
#interface ChildViewController : UIViewController{
NSArray *strings;
UITextfield *textField1;
UITextfield *textField2;
}
...
- (void)viewDidLoad {
[super viewDidLoad];
textField1.text = [strings objectAtIndex:0];
textField2.text = [strings objectAtIndex:1];
}
Then in the parent class:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ChildViewController *childController = [[ChildViewController alloc] init];
childController.strings = your_array_of_strings;
[self.navigationController pushViewController:childController animated:YES];
[childController release];
}
- (id)initWithDataObject:(YourDataObjectClass *)dataObject {
if (self = [super init]) {
self.dataObject = dataObject;
// now you can do stuff like: self.myString = self.dataObject.someString;
// you could do stuff like that here or if it is related to view-stuff in viewDidLoad
}
return self;
}
If you want to get really fancy, you can make a delegate for your child view.
#protocol MyChildViewDelegate
- (NSArray*)getStringsForMyChildView:(MyChildView*)childView;
#end
#interface MyChildView : UIView
{
id <MyChildViewDelegate> delegate;
...
}
#property (nonatomic, assign) id <MyChildViewDelegate> delegate;
...
#end
Then somewhere in your view you would ask for the strings:
- (void)viewDidLoad
{
...
NSArray* strings = [delegate getStringsForMyChildView:self];
...
}
Then in your controller (or where ever) you can do:
myChildView = [[MyChildView alloc] initWith....];
myChildView.delegate = self;
...
- (NSArray*)getStringsForMyChildView:(MyChildView*)childView
{
return [NSArray arrayWithObjects:#"one", #"two", #"three", nil];
}
It's probably a little overkill in this case, but this is how UITableViews do it too: they have a data source delegate to provide them with their contents.