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

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);

Related

how to decode multiple objects from data stored in file in iOS

I have a form with information first name and last name and some other information. I use a person class to store this information. on submit click I archiving it in a file person.txt using NSCoding implemented in person class. if I add multiple persons in the file person.txt, how can I get all the person objects stored in the file. decoding the person class just gives me the last added person.
If you want all of the person objects serialized, then you need the NSArray or whatever other collection class in which they are stored to be the root object for the NSKeyedArchiver. e.g.: (assumes ARC)
#import <Foundation/Foundation.h>
#interface Person:NSObject <NSCoding>
#property (nonatomic, copy) NSString *lastName;
#property (nonatomic, copy) NSString *firstName;
// etc.
#end
#implementation Person
#synthesize lastName = _lastName;
#synthesize firstName = _firstName;
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.lastName forKey:#"ln"];
[aCoder encodeObject:self.firstName forKey:#"fn"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if( !self ) { return nil; }
_lastName = [aDecoder decodeObjectForKey:#"ln"];
_firstName = [aDecoder decodeObjectForKey:#"fn"];
return self;
}
#end
int main(int argc, char *argv[]) {
NSAutoreleasePool *p = [[NSAutoreleasePool alloc] init];
Person *me = [Person new];
me.lastName = #"Kitten";
me.firstName = #"Mittens";
Person *you = [Person new];
you.lastName = #"Youe";
you.firstName = #"JoJo";
NSArray *people = [NSArray arrayWithObjects:me,you,nil];
NSData *serializedData = [NSKeyedArchiver archivedDataWithRootObject:people];
// write your serializedData to file, etc.
[p release];
}
Why the .txt extension on your archive, though? It just binary data, right?

NSMutableArray crashes when adding after proper initialization

I have an NSMutableArray defined as a property, synthesized and I have assigned a newly created instance of an NSMutableArray. But after this my application always crashes whenever I try adding an object to the NSMutableArray.
Page.h
#interface Page : NSObject
{
NSString *name;
UIImage *image;
NSMutableArray *questions;
}
#property (nonatomic, copy) NSString *name;
#property (nonatomic, retain) UIImage *image;
#property (nonatomic, copy) NSMutableArray *questions;
#end
Page.m
#implementation Page
#synthesize name, image, questions;
#end
Relevant code
Page *testPage = [[Page alloc] init];
testPage.image = [UIImage imageNamed:#"Cooperatief leren Veenman-11.jpg"];
testPage.name = [NSString stringWithString:#"Cooperatief leren Veenman-11.jpg"];
testPage.questions = [[NSMutableArray alloc] init];
[testPage.questions addObject:[NSNumber numberWithFloat:arc4random()]];
The debugger reveals that the moment I use testPage.questions = [[NSMutableArray alloc] init]; the type of testPage.questions changes from NSMutableArray* to __NSArrayL* (or __NSArrayI*, not sure). I suspect this to be the problem, but I find it extremely odd. Anyone know what's happening here?
The problem is that you've declared the property as copy. This means your setter is going to be implemented something like this:
- (void) setQuestions:(NSMutableArray *)array {
if (array != questions) {
[questions release];
questions = [array copy];
}
}
The kicker here is that if you -copy an array (whether immutable or mutable), you will always get an immutable NSArray.
So to fix this, change the property to be retain instead of copy, and also fix this memory leak:
testPage.questions = [[NSMutableArray alloc] init];
It should be:
testPage.questions = [NSMutableArray array];
#property (nonatomic, copy) This setter declaration "copy" probably cast to NSArray why not retain or assign? I would retain anyway
You can also create a mutable copy method like so:
- (void)setQuestions:(NSMutableArray *)newArray
{
if (questions != newArray)
{
[questions release];
questions = [newArray mutableCopy];
}
}

passing NSString from one class to the other

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.

Wondering do i have a mem leak(reported as potential)

I create a NSMutableString called mutableScoreHolder outside my do-while loop.
I alloc it, 'copy' it into an other object called a 'Match' that contains a NSString.
When I build and analyze the code it reports a potential memory leak of my mutableScoreHolder.
NSString * scoreHolder;
NSMutableString * mutableScoreHolder;
count = 1;
numMatchCounter = 0;
int startOfScoreIndex = 0;
int endOfScoreIndex = 0;
int numberOfGoals=0;
do
{
match = [substring rangeOfString: #"points_bg"];
if (match.location == NSNotFound)
{
break;
}
if ((match.location + match.length) > ([substring length]))
{
break;
}
substring = [substring substringFromIndex:(match.location + match.length)];
match2 = [substring rangeOfString: #">"];
startOfScoreIndex = match2.location+1;
match2 = [substring rangeOfString: #"<"];
endOfScoreIndex = match2.location;
if ((count % 2) == 1)
{
scoreHolder = [substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))];
mutableScoreHolder = [[NSMutableString alloc] initWithString:scoreHolder];
numberOfGoals += [scoreHolder intValue];
}
else
{
Match *aMatch = [theMatchScoresArray objectAtIndex:(numMatchCounter)];
numberOfGoals += [[substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))] intValue];
[scoreHolder stringByAppendingString:#" - "];
[mutableScoreHolder appendString:#" - "];
[scoreHolder stringByAppendingString:[substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))]];
[mutableScoreHolder appendString:[substring substringWithRange:NSMakeRange(startOfScoreIndex, (endOfScoreIndex-startOfScoreIndex))]];
aMatch.theScore = [mutableScoreHolder copy];
aMatch.matchGoalCount = numberOfGoals;
numMatchCounter++;
numberOfGoals=0;
}
count++;
}
while ( match.length != 0 );
Here is my Match Object Class.
#interface Match : NSObject
{
NSString *teamName1;
NSString *teamName2;
NSString *theScore;
int matchGoalCount;
NSMutableArray *scorersArray;
NSMutableArray *scorerOrderArray;
NSString *matchStatus;
NSString *matchDate;
bool matchNotStarted;
}
#property(nonatomic) int matchGoalCount;
#property(nonatomic) bool matchNotStarted;
#property(nonatomic, retain) NSString *teamName1;
#property(nonatomic, retain) NSString *teamName2;
#property(nonatomic, retain) NSString *theScore;
#property(nonatomic, retain) NSString *matchStatus;
#property(nonatomic, retain) NSString *matchDate;
#property(nonatomic, retain) NSMutableArray *scorersArray;
#property(nonatomic, retain) NSMutableArray *scorerOrderArray;
-(id)init;
#end
#import "Match.h"
#implementation Match
#synthesize teamName1;
#synthesize teamName2;
#synthesize theScore;
#synthesize scorersArray;
#synthesize matchDate;
#synthesize matchStatus;
#synthesize matchGoalCount;
#synthesize scorerOrderArray;
#synthesize matchNotStarted;
-(id)init
{
//NSLog(#"****** MATCH INIT ******");
self = [super init];
scorersArray =[[NSMutableArray alloc] init];
scorerOrderArray =[[NSMutableArray alloc] init];
return self;
}
-(void) dealloc
{
[scorersArray release];
[scorerOrderArray release];
[teamName1 release];
[teamName2 release];
[theScore release];
[matchStatus release];
[matchDate release];
[scorersArray release];
[scorerOrderArray release];
[super dealloc];
}
#end
I do find there there is a string leaked when i run instruments checking for leaks. So I think this 'potential leak' might be the leak I see.
Because the scores has a retain
#property(nonatomic, retain) NSString *theScore;
And there is a string copied into it
aMatch.theScore = [mutableScoreHolder copy];
Could that give a retain count of 2? And so then leak?
Sorry for the complicated question! Has my head spinning trying to get my head around it.
Thanks
-Code
You're definitely leaking here, for 2 separate reasons.
The first is you're alloc/init'ing an NSMutableString and stuffing it into mutableScoreHolder. This is a local variable, and as soon as this value goes out of scope (or gets replaced the next time a new array is created) the old value is leaked. This should be an autoreleased value instead, as in [NSMutableString stringWithString:scoreHolder].
The second is you're copying the string and stuffing the resulting value into a property. What you should do is redeclare that property as copy
#property(nonatomic, copy) NSString *theScore;
and then just assign mutableScoreHolder to that property directly
aMatch.theScore = mutableScoreHolder
With your existing code, you copy the array, and then the property retains it. With this change, the property copies it directly, and no extra retains are used.
Note, in general it's a good idea to declare properties with supported types as copy. This includes things like NSString, NSArray, NSDictionary, etc. If you're assigning an already-immutable object to the property, the copy falls back to retain instead and there's no performance hit. But in situations like yours where you're assigning mutable objects, it will copy it as appropriate and keep an immutable snapshot in the property.
And there is a string copied into it
aMatch.theScore = [mutableScoreHolder copy];
Could that
give a retain count of 2? And so then
leak?
exactly. You could change the property of theScore from retain to copy to fix this. THen you can use aMatch.theScore = mutableScoreHolder;
and there is (at least) one other leak:
mutableScoreHolder = [[NSMutableString alloc] initWithString:scoreHolder];
this gets never released.

Pass variables from function to function

I'm just learning Objective-C and have a what I'm sure is a pretty basic question here.
This is a function I've created that will simple hold variables from some user input.
- (void)standardDatabaseWithName:(NSString*)name
host:(NSString*)host
username:(NSString*)username
password:(NSString*)password
database:(NSString*)database
port:(NSInteger*)port {
NSString *myName = name;
NSString *myHost = host;
NSString *myUsername = username;
NSString *myPassword = password;
NSString *myDatabase = database;
NSInteger *myPort = port;
}
Below is a seperate function where I want to create a new var with that information and the from there use it was what I need.
- (void)insertStandardConnection {
NSString name = [NewDbModalView standardDatabaseWithName:myName];
NSString host = [NewDbModalView standardDatabaseWithName:myHost];
}
So this attempt didn't work for me. Any advice here guys? At this point I've been left scratching my head.
I would suggest creating an object to hold all of that information and just pass the object around
Every time you call the method, you have to provide all of the variables:
[NewDbModalView standardDatabaseWithName:myName host:myHost username:aUsername password:aPassword database:aDatabase port:aPort];
So, when you call [NewDbModalView standardDatabaseWithName:myName], that method doesn’t exist.
The variables you declare in standardDatabaseWithName:... are local to that method. You need to store (copies of) that data inside the object. Although, looking at your code, I wonder if you're trying to set default values? In that case, you might want static global variables to take the values, and then you'd need -(void)standardDatabaseWithName:... to become +(void)setStandardDatabaseName:(NSString *)name ....
In your .h file you should declare properties
#interface standardDatabaseWithNameObject : NSObject{
NSString *myName;
NSString *myHost;
NSString *myUsername ;
NSString *myPassword;
NSString *myDatabase;
NSInteger *myPort;
}
#property (nonatomic, retain) NSString *myName;
#property (nonatomic, retain) NSString *myHost;
#property (nonatomic, retain) NSString *myUsername ;
#property (nonatomic, retain) NSString *myPassword;
#property (nonatomic, retain) NSString *myDatabase;
#property (nonatomic, retain) NSInteger *myPort;
etc...
Then in your implementation you need to synthesize the properties and they will be available for use:
#synthesize myName, myHost, myUsername, myPassword, myDatabase, myPort;
- (void)standardDatabaseWithName:(NSString*)name
host:(NSString*)host
username:(NSString*)username
password:(NSString*)password
database:(NSString*)database
port:(NSInteger*)port {
myName = name;
myHost = host;
myUsername = username;
myPassword = password;
myDatabase = database;
myPort = port;
}
- (void)insertStandardConnection {
NSString name = myName;
NSString host = myHost;
}
- (void) dealloc
{
[myName release];
[myHost release];
[myUsername release];
[myPassword release];
[myDatabase release];
[myPort release];
}
Good Luck