passing NSString from one class to the other - iphone

I have a NSString that is taken from a UITextField in a ViewController. Every of my other ViewController will use this NSString as well. How can I pass this NSString to others ViewControllers?

You want to have a property in each of your controllers
#interface MyViewController : UIViewController{
NSString *title;
}
#property (retain) NSString *title;
#end;
#implementation MyViewController
#synthesize title;
#end;
Use it like:
MyViewController *myVC = [[MyViewController alloc] initWithFrame:...];
myVC.title = #"hello world";
You should be familiar with Memory Management

Create a class for sharing your common objects. Retrieve it using a static method, then read and write to its properties.
#interface Store : NSObject {
NSString* myString;
}
#property (nonatomic, retain) NSString* myString;
+ (Store *) sharedStore;
#end
and
#implementation Store
#synthesize myString;
static Store *sharedStore = nil;
// Store* myStore = [Store sharedStore];
+ (Store *) sharedStore {
#synchronized(self){
if (sharedStore == nil){
sharedStore = [[self alloc] init];
}
}
return sharedStore;
}
// your init method if you need one
#end
in other words, write:
Store* myStore = [Store sharedStore];
myStore.myString = #"myValue";
and read (in another view controller):
Store* myStore = [Store sharedStore];
myTextField.text = myStore.myString;

If the string remains the same, and never changes, you could make a file named defines.h (without the .m file) and have this line:
#define kMyString #"Some text"
Then wherever you need the string, just import the defines file and use the constant.
#import "defines.h"
Much simpler than making custom classes.
EDIT:
Didn't see you needed to grab from the text field.
In that case, you could have it stored as property of your app delegate class and get it from there. The delegate can be accessed from anywhere in your app.

Related

How can i use id as a temporary storage for a variable value

I am new to programming so can anyone here please let me know if the below is the valid in Objective-C.
Thanks.
#interface MainViewController : UIViewController
{
id iTempStore;
}
#property (nonatomic, assign) id iTempStore;
// FirstViewController
#interface FirstViewController : UIViewController
{
MainViewController* pParent;
}
-(void) SomeFunction
{
m_pParent = [[[MainViewController]alloc]init];
NSString* pTest = [[[NSString alloc] initWithString:#"Test"]autorelease];
// Is this valid way to store an object ???
[m_pParent setITempStore: pTest];
// Check Value
NSString* pValue = [m_pParent iTempStore];
NSLog(#"Value is: %#", pValue);// Value is: Test
[m_pParent release];
}
id can hold a reference to any object, so storing a string there is fine, but since you are backing with an iVar you probably want to use copy or retain rather than assign as your propery storage class... you would use copy if it were alway NSString or any class that has a mutable subclass... but since id can't specify that to be type safe you would either do :
#property(copy) id <NSCopying> iTempStore;
or
#propery(retain) id iTempStore;
it's technically ok...but not very...good
If you're declaring a property you don't necessary need it as instance variable too.
Do not use non-ARC things ...ARC is supported on all ios devices ( not sure about first gen) but on all that really matter at least.
If you know the object type you don't need to use id. id is used for when you are not sure of the returning type.
your code should look something like this :
#interface MainViewController : UIViewController
#property (nonatomic, assign) NSString* iTempStore;
// FirstViewController
#interface FirstViewController : UIViewController
{
MainViewController* pParent;
}
-(void) SomeFunction
{
m_pParent = [[MainViewController alloc]init];
NSString* pTest = [[[NSString stringWithString:#"Test"];
[m_pParent setITempStore: pTest];
NSString* pValue = [m_pParent iTempStore];
NSLog(#"Value is: %#", pValue);
}

instanced variable accessed in class method, Objective C

This is the original codes when I am getting this error
ClassA.h
+(ClassA*)methodA:(NSData*)data;
#property (nonatomic, strong) NSMutableArray *arr;
#property (nonatomic, strong) RXMLElement *rxmlRoot;
#end
ClassA.m
+(ClassA*)methodA:(NSData*)data {
//NSLog(#"class is %#",[name class]);
ClassA *ClassA = [[Stores alloc] init];
arr = [NSMutableArray array];
rxmlRoot = [RXMLElement elementFromXMLData:data];
}
I am reviewing my codes and now I have tow options to fix the code
OptionA
ClassA.h
+(ClassA*)methodA:(NSData*)data;
#property (nonatomic, strong) NSMutableArray *arr;
#property (nonatomic, strong) RXMLElement *rxmlRoot;
#end
ClassA.m
+(ClassA*)methodA:(NSData*)data {
//NSLog(#"class is %#",[name class]);
ClassA *ClassA = [[Stores alloc] init];
ClassA.arr = [NSMutableArray array]; <----- this has been modified
ClassA.rxmlRoot = [RXMLElement elementFromXMLData:data];<----- this has been modified
}
OptionB
ClassA.h
+(ClassA*)methodA:(NSData*)data;
#end
ClassA.m
static RXMLElement *rxlRoot; <----- this has been added as class variable
static NSMutableArray *arr; <----- this has been added as class variable
+(ClassA*)methodA:(NSData*)data {
//NSLog(#"class is %#",[name class]);
ClassA *ClassA = [[Stores alloc] init];
arr = [NSMutableArray array];
rxmlRoot = [RXMLElement elementFromXMLData:data];
}
I try either optionA or optionB and the compiler does not complain anything and the codes work properly.
I see many posts following the optionB which create class variables.
Question: is optionA also a good way to follow when we are dealing with class method and class variable as well.
Please advice me on this issue and by the way if I have made mistakes somewhere, please correct me. Thanks
There is no such thing as a "class variable" in Objective-C. When you declare a variable as static it is, effectively, a global variable that is limited to either the scope of the file it is compiled within or the scope of a method/function (or sub-expression).
Get rid of the Class. part of your calls to set the variables; that'll work in the .m file for the Class only; which is generally the pattern you would want (truly global variables are generally discouraged -- sometimes useful, though).
Create a designated initializer with a data parameter. Every class should have a designated initializer.
In your class method call the designated initializer passing in data.
Here is example code:
//ClassA.h
#class RXMLElement;
#interface ClassA : NSObject
+(ClassA*)methodA:(NSData*)data;
-(id)initWithData:(NSData*)data;
#property (nonatomic, strong) NSMutableArray *arr;
#property (nonatomic, strong) RXMLElement *rxmlRoot;
#end
//ClassA.m
#implementation ClassA
#synthesize arr;
#synthesize rxmlRoot;
+(ClassA*)methodA:(NSData*)data {
return [[ClassA alloc] initWithData:data];
}
-(id)initWithData:(NSData*)data {
self = [super init];
if (self) {
arr = [NSMutableArray array];
rxmlRoot = [RXMLElement elementFromXMLData:data];
}
return self;
}
#end
ARC is assumed in the example.

how to pass a string value from one .m file to another .m file

Hi i am new to objective c. i have a .m file in which i have the string to be passed.
NSString *passedMonth;
i am Passing it like this
KLTile *kltil = [[KLTile alloc] inittempMonth:passedMonth];
temp month is string in other .m file
-(id)inittempMonth:(NSString *)tem{
tempMonth = [[NSString alloc]init];
self.tempMonth = tem;
NSLog(#" temp month....%#",self.tempMonth);
return self;
}
the log inside the init is giving the output but the same log outside the init method doe't works......
i want to use the tempMonth string outside the -(id)inittempMonth:(NSString *)tem{...
is there any way to use the string outside the init method...
Your init method is wrong. So you should modify it into something like:
- (id)initWithTempMonth:(NSString *)tem{
{
self = [super init]; // This line is important
if (self) {
self.tempMonth = tem;
NSLog(#" temp month....%#",self.tempMonth);
}
return self;
}
Also, don't forget to declare tempMonth as a retained property in the .h file:
#property (nonatomic, retain) NSString *tempMonth;
Or if you are using ARC:
#property (nonatomic, strong) NSString *tempMonth;
Then you can log the value of the property like this:
KLTile *kltil = [[KLTile alloc] inittempMonth:passedMonth];
NSLog(#"Temp month: %#", kltil.tempMonth);

accessing class file crashes when scrolling starts (UIScrollview)

hopefully someone will be able to help me. I have a UIScrollView on my page. The .h file has set the UIscrollviewdelegate.
I have a class file called "Picture.h / Picture.m".
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename {
self.name = aName;
self.filename = aFilename;
return self;
}
In this class file, I simply set a couple of strings. I load an array with object of this picture class, for example
Picture *image2 = [[Picture alloc] initWithName:#"Apple" filename:#"apple.png"];
[pictureArray addObject: image2];
[image2 release];
Within my viewController, I call this class and assign is as such
Picture *thisPicture = (Picture *)[appDelegate.pictureArray objectAtIndex:0];
view2image.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", thisPicture.filename]];
The above works fine. The image is set to what ever I put, example, "apple.png". However, when I tried to set this in the - (void) scrollViewDidScroll:(UIScrollView *) method within my viewController, I get a bad exec error and the app crashes.
Yet, if I had an array of filenames (so not storing my class object in the array) and access objectAtIndex:0 in the scrollViewDidScroll - it works fine.
So, this code is OK
nextImageView.image = [UIImage imageNamed: [NSString stringWithFormat:#"%#", [appDelegate.pictureCardsArray objectAtIndex:0]]];
but this crashes
Picture *image3 = (Picture *)[appDelegate.pictureArray objectAtIndex:0];
nextImageView.image = [UIImage imageNamed:[NSString stringWithFormat:#"%#", image3.filename]];
Interestingly though, if I don't try to access the element of image3 (eg image3.filename) it doesn't crash. This is useless though! Also, if I disable the delegate = self for the uiscrollview, then this code works, but none of the scrolling actions are fired. I came across this post (http://stackoverflow.com/questions/1734720/uiscrollview-on-a-uiviewcontroller) when searching for the solution, but cannot see where I might be releasing the viewController early. To be safe, nothing is getting released (yet!)
Hopefully someone might be able to shed some light on it!!
[edit]Just adding in the full class files][/edit]
Picture.h
#import <UIKit/UIKit.h>
#interface Picture : NSObject {
NSString *name;
NSString *filename;
}
#property (nonatomic, copy) NSString *name;
#property (nonatomic, copy) NSString *filename;
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename;
#end
Picture.m
#import "Picture.h"
#implementation Picture
#synthesize name, filename;
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename {
self.name = aName;
self.filename = aFilename;
return self;
}
#end
Just for completeness... the solution was as Antwen Van Houdt said - I changed copy to retain and it worked fine.
#import <UIKit/UIKit.h>
#interface Picture : NSObject {
NSString *name;
NSString *filename;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, retain) NSString *filename;
- (id)initWithName:(NSString *)aName filename:(NSString *)aFilename;
#end

EXC_BAD_ACCESS when calling class init in Objective C

I've been trying to figure this out but I can't figure out what I'm doing wrong.
I wrote a class and whenever I try to initialize it, I get a EXC_BAD_ACCESS error. I can't even step into the initialization.
Anyone have any idea what I'm doing wrong?
User *myUser = [myUser init];
.h file:
#import <Foundation/Foundation.h>
#interface User : NSObject {
long rowId;
NSString *email;
NSString *password;
NSString *fileVersion;
}
#property long rowId;
#property (assign) NSString *email;
#property (assign) NSString *password;
#property (assign) NSString *fileVersion;
#end
.m file
#import "User.h"
#implementation User
#synthesize rowId, email, password, fileVersion;
-(id)init {
self = [super init];
return self;
}
#end
You have to actually allocate the object:
User *myUser = [[User alloc] init];
Don't forget to release it when you're done using it.