Pass variables from function to function - iphone

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

Related

Singleton changes is not preserved to the next view IOS

I have a singleton class which I intend to share throughout my whole application.
It looks like this:
.m
#implementation PersonalGlobal
#synthesize firstName;
#synthesize lastName;
#synthesize SSN;
#synthesize customerNo;
#synthesize email;
#synthesize address;
#synthesize city;
#synthesize postalCode;
#synthesize telNo;
#synthesize mobileNo;
#pragma mark Singleton Methods
+ (id)sharedPersonal {
static PersonalGlobal *sharedPersonalGlobal = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedPersonalGlobal = [[self alloc] init];
});
return sharedPersonalGlobal;
}
- (void)dealloc {
[super dealloc];
// Should never be called
}
#end
.h
#import <foundation/Foundation.h>
#interface PersonalGlobal : NSObject {
NSString *firstName;
NSString *lastName;
NSString *SSN;
NSString *customerNo;
NSString *email;
NSString *address;
NSString *city;
NSString *postalCode;
NSString *telNo;
NSString *mobileNo;
}
#property (nonatomic, retain) NSString *firstName;
#property (nonatomic, retain) NSString *lastName;
#property (nonatomic, retain) NSString *SSN;
#property (nonatomic, retain) NSString *customerNo;
#property (nonatomic, retain) NSString *email;
#property (nonatomic, retain) NSString *address;
#property (nonatomic, retain) NSString *city;
#property (nonatomic, retain) NSString *postalCode;
#property (nonatomic, retain) NSString *telNo;
#property (nonatomic, retain) NSString *mobileNo;
+ (id)sharedPersonal;
#end
In the code I save strings to it like so:
PersonalGlobal *sharedPersonal = [PersonalGlobal sharedPersonal];
sharedPersonal.firstName = #"Some string";
But when I change view and try to access the string like this:
PersonalGlobal *sharedPersonal = [PersonalGlobal sharedPersonal];
//Setting some textfield
sometextfield.text = sharedPersonal.firstName;
I get nothing. I have done a #import "PersonalGlobal.h" in all the files.
Can i commit the changes in any way to the singleton class?
Can anyone see what I am doing wrong here?
Thanks!
Your implementation is looking fine. This should work if your singleton returning the only one instance . So the point of doubt in your sharedPersonal method . Just try to add breakpoints in this method and see whether it is creating a new instance every time .for the reference I got this SO question.
If not then you can also try this :
+(SingleTon *)getSharedInstance
{
static PersonalGlobal *sharedPersonalGlobal = nil;
if (sharedPersonalGlobal==nil)
{
sharedPersonalGlobal=[[PersonalGlobal alloc]init];
}
return sharedPersonalGlobal;
}
This is working code for me.
Your singleton implementation looks ok. I wouldn't be surprised if in this case the code that you wrote to set the firstName just never gets executed. If I were you I would step through the codes.

How do I get out data from my NSDirectory (not just a property typo)?

I'm missing something simple I think, but been at it for days now without solving this. Even Started to create a "work-around" just to solve it for now, but still want to solve this the "right" way. Any suggestions? Thank's!
.
The problem:
Seems to be missing the class Adealer (get error "-[Adealer objectAtIndex:]: unrecognized selector sent to instance 0x8c5f8b0"), but I did the import Adealer.h to this "detailsVC". But it's not just a simple error of naming the property wrong (objectForKey:#"CustName" instead of "custname" etc - tested this a lot).
Also, I've got similar "listVC"s without a class like Adealer in them, that also transfer data the same way to the same "detailsVC" and they work just fine! Then I just get the data with calls like;
self.labelRestName.text = [restDetails objectForKey:#"CustName"];
Overview:
I got a tableViewController "listVC" that creates the data and show a list, then a ViewController "detailsVC" to show the details. The data (selected row object in "listVC" is transfered via a seque and "destVC.restGPSTransfer" (NSDictionary). The data arrives ok in the "detailsVC" and looks like this in the terminal;
dealerName = Uppsala Centrum Test
dealerAdressStreet = Dragarbrunnsgatan 55
dealerAdressZip = 75320
dealerAdressCity = Uppsala
dealerLongitude = 17.63893
dealerLatitude = 59.85856
dealerDistance2 = 8586398.000000
etc
.
Following the data:
"listVC"
1) First fetching data from web via a AFNetworking json object into an NSMutableArray "restFeed" - ok.
2) Then creating my own data to an NSMutableArray within this loop into a NSMutableArray "updatedDealers" - ok;
NSMutableArray *updatedDealers = [[NSMutableArray alloc]init];
while (i+1 < [_restFeed count]) {
i++;
// Get dealer position function here
// Get distance function here
// Then create my own data here (also #imported Adealer to "listVC";
Adealer *theDealer = [[Adealer alloc]init];
theDealer.dealerName = [[_restFeed objectAtIndex:i]objectForKey:#"CustName"];
theDealer.dealerLongitude = [[_restFeed objectAtIndex:i]objectForKey:#"long"];
theDealer.dealerLatitude = [[_restFeed objectAtIndex:i]objectForKey:#"lat"];
theDealer.dealerDistance2 = theDistance;
// etc...
// Check if data ok
NSLog(#"theDealer = %#",[theDealer description]);
// Don't add dealer object without positiondata to the new array
if (![theDealer.dealerLatitude isEqualToString:#""]) {
[updatedDealers addObject:theDealer];
}
3) Then I use NSSortdescriptor to sort the dealers in NSMutableArray "updatedDealers" into distance order and finally creates the new NSMutableArray "restFeed" with this; (also did "#synthesize dealerFeed = _dealerFeed;" in "listVC") - ok.
_dealerFeed = [NSMutableArray arrayWithArray:sortedContestArray];
4) The populating some tableViewCells with this array and it works just fine - ok.;
cell.cellDealerName.text = [NSString stringWithFormat:#"%#",[[_dealerFeed objectAtIndex:indexPath.row]dealerName]];
5) In the function didSelectRowAtIndexPath transfer the selected object with the "detailsVC"'s NSDictionary "restGPSTransfer" - ok;
destVC.restGPSTransfer = [_dealerFeed objectAtIndex:myIndexPath.row];
"detailsVC":
6) The data seems to transfer ok (se top of this post) but when trying to call the data with;
self.labelRestName.text = [restGPSTransfer objectForKey:#"dealerName"];
I get this error and the app crashes: "-[Adealer objectAtIndex:]: unrecognized selector sent to instance 0x8c5f8b0".
Some more testing done...
Tried to verify the structure + it's keys and properties of the NSDictionary "restGPSTransfer", but using description only got me so far. And have not solved my problem and I still get the "unrecognized selector" error. Could it maybe have become dictionaries within dictionary's or something?
Constructed this little simple if-test to see if the property is really there. But I have to check every property "manually". There's propably a smarter way to check the hole NSDictionary / NSArray?
if ([restGPSTransfer objectForKey:#"dealerName"]) {
NSLog(#"= YES! key exists.");
} else {
NSLog(#"= Nope! key don't exists");
}
THANK'S for any help on this :-)
.
UPDATE the Adealer class files;
Adealer.h
#import <Foundation/Foundation.h>
#interface Adealer : NSObject
#property (nonatomic, retain) NSString * dealerName;
#property (nonatomic, retain) NSString * dealerAdressCity;
#property (nonatomic, retain) NSString * dealerAdressStreet;
#property (nonatomic, retain) NSString * dealerAdressZip;
#property (nonatomic, retain) NSNumber * dealerID;
#property (nonatomic, retain) NSString * dealerImages;
#property (nonatomic, retain) NSString * dealerLogo;
#property (nonatomic, retain) NSString * dealerMail;
#property (nonatomic, retain) NSString * dealerProducts;
#property (nonatomic, retain) NSString * dealerTel;
#property (nonatomic, retain) NSString * dealerText;
#property (nonatomic, retain) NSString * dealerWeb;
#property (nonatomic, retain) NSString * dealerLongitude;
#property (nonatomic, retain) NSString * dealerLatitude;
#property (nonatomic, retain) NSString *dealerDistance;
#property float dealerDistance2;
#end
Adealer.m
#import "Adealer.h"
#implementation Adealer
#synthesize dealerAdressCity, dealerAdressStreet, dealerAdressZip, dealerID, dealerImages, dealerLogo;
#synthesize dealerMail, dealerName, dealerProducts, dealerTel, dealerText, dealerWeb;
#synthesize dealerLongitude, dealerLatitude, dealerDistance,dealerDistance2;
- (NSString *)description {
// Added extension of description
NSMutableString *string = [NSMutableString string];
[string appendString:#"\ntheDealer object and it's properties:\n"];
[string appendFormat:#"dealerName = %#\n", dealerName];
[string appendFormat:#"dealerAdressStreet = %#\n", dealerAdressStreet];
[string appendFormat:#"dealerAdressZip = %#\n", dealerAdressZip];
[string appendFormat:#"dealerAdressCity = %#\n", dealerAdressCity];
[string appendFormat:#"dealerTel = %#\n", dealerTel];
[string appendFormat:#"dealerMail = %#\n", dealerMail];
[string appendFormat:#"dealerWeb = %#\n", dealerWeb];
[string appendFormat:#"dealerLogo = %#\n", dealerLogo];
[string appendFormat:#"dealerImages = %#\n", dealerImages];
[string appendFormat:#"dealerText = %#\n", dealerText];
[string appendFormat:#"dealerProducts = %#\n", dealerProducts];
[string appendFormat:#"dealerLongitude = %#\n", dealerLongitude];
[string appendFormat:#"dealerLatitude = %#\n", dealerLatitude];
[string appendFormat:#"dealerDistance = %#\n", dealerDistance];
[string appendFormat:#"dealerDistance2 = %f\n\n", dealerDistance2];
return string;
}
#end
SOLVED!
Posted if anyone else needs it here.
The solution
In my "detailsVC" I first did this iVar declaration;
.h:
Adealer *theDealer;
#property (nonatomic, retain) Adealer *theDealer;
.m:
#synthesize theDealer;
Then in my "listVC" i did this to transfer the Adealer object and it's properties to the "detailsVC" (remember that the Adealer object already has got it's properties earlier in the described "loop");
Instead of my earlier;
destVC.restGPSTransfer = [_dealerFeed objectAtIndex:myIndexPath.row];
I changed it to;
destVC.theDealer = [_dealerFeed objectAtIndex:myIndexPath.row];
And to actually show and check the transferred property in "detailsVC" I can now simply call this to get the dealers name (or any other properties);
self.labelRestName.text = theDealer.dealerName;
NSLog(#"theDealer.name = %#",theDealer.dealerName);
Works great! Happy Coding everyone!

using an NSArray in a custom class isn't working

Starting over. I am fairly new to objective C. I have created the following class and I can't figure out how to initialize the array.
Can anyone provide any guidance on how to initialize the NSArray?
StatusPost.m
#import "StatusPost.h"
#implementation StatusPost
#synthesize messageId, fromName, friendId, message, choice2, choice3, choice4, picture, fbImage, commentCount, commentArray;
-(id)initWithMessageId:(NSString*) rMessageId
fromName:(NSString*) rFromName
friendId:(NSString*) rFriendId
message:(NSString*) rMessage
choice2:(NSString*) rChoice2
choice3:(NSString*) rChoice3
choice4:(NSString*) rChoice4
picture:(NSString *) rPicture
fbImage:(UIImage *)rfbImage
commentCount:(NSString*) rCommentCount
commentArray:(NSArray*) rCommentArray
{
if (self = [super init]) {
commentArray = [NSArray new];
self.messageId = rMessageId;
self.fromName = rFromName;
self.friendId = rFriendId;
self.message = rMessage;
self.choice2 = rChoice2;
self.choice3 = rChoice3;
self.choice4 = rChoice4;
self.picture = rPicture;
self.fbImage = rfbImage;
self.commentCount = rCommentCount;
self.commentArray = rCommentArray;
}
return self;
}
- (void)dealloc {
[messageId release];
[fromName release];
[friendId release];
[message release];
[picture release];
[fbImage release];
[commentCount release];
[commentArray release];
[super dealloc];
}
#end
StatusPost.h:
#import
#interface StatusPost : NSObject {
NSString* messageId;
NSString* fromName;
NSString* friendId;
NSString* message;
NSString* choice2;
NSString* choice3;
NSString* choice4;
NSString* picture;
UIImage* fbImage;
NSString* commentCount;
NSArray* commentArray;
}
#property (nonatomic, retain) NSString* messageId;
#property (nonatomic, retain) NSString* fromName;
#property (nonatomic, retain) NSString* friendId;
#property (nonatomic, retain) NSString* message;
#property (nonatomic, retain) NSString* choice2;
#property (nonatomic, retain) NSString* choice3;
#property (nonatomic, retain) NSString* choice4;
#property (nonatomic, retain) NSString* picture;
#property (nonatomic, retain) UIImage* fbImage;
#property (nonatomic, retain) NSString* commentCount;
#property (nonatomic, retain) NSArray* commentArray;
-(id)initWithMessageId:(NSString*) rMessageId
fromName:(NSString*) rFromName
friendId:(NSString*) rFriendId
message:(NSString*) rMessage
choice2:(NSString*) rChoice2
choice3:(NSString*) rChoice3
choice4:(NSString*) rChoice4
picture:(NSString*) rPicture
fbImage:(UIImage*) rfbImage
commentCount:(NSString*) rCommentCount
commentArray:(NSArray*) rCommentArray;
#end
It is likely that you aren't ever initializing the array, so when you try to add an object, you are just sending a message to nil. In the custom class's init method, add the line:
commentArray = [NSMutableArray new];
[NSArray new] is shorthand for [[NSArray alloc] init], so, technically speaking, that statement "inits" the NSArray.
However, your code looks a bit peculiar. You have the following statements in your init:
commentArray = [NSArray new];
self.commentArray = rCommentArray;
The first statement is setting the instance variable commentArray to the address of the newly alloced/inited NSArray while the second is setting the property commentArray to a parameter value. However, you have (through the #synthesize) made the instance variable commentArray the "backing store" for the property commentArray, so when you execute the second line the effect of the first line is overwritten (and the NSArray you created is "leaked").
(But if your real question is how to "load" an NSArray with values, you should ask that question -- and you'll get different answers.)

add data to my data member

Hello I'm new to iPhone development.
I try to add move data from NSDictionary to data member of calls that i created.
When i "setWeightMeasure" nothing happened.
any suggestions?
the code that don't work:
NSDictionary *responseBodyProfile = [responseBody objectFromJSONString];
NSLog(#"%#",responseBodyProfile);
// the output is :
"{ "profile": {"goal_weight_kg": "77.0000", "height_cm": "179.00",
"height_measure": "Cm", "last_weight_date_int": "15452",
"last_weight_kg": "99.0000", "weight_measure": "Kg" }}""
[responseBody release];
if (responseBodyProfile != nil ){
NSDictionary *profile =[responseBodyProfile valueForKey:#"profile"];
NSLog(#"%#\n",[profile objectForKey:#"weight_measure"]);// Output : "kg"
[self.myUser setWeightMeasure:[profile objectForKey:#"weight_measure"]];
NSLog(#"%#", [self.myUser WeightMeasure]); // Output : "(null)"
}
the H file properyty:
#property (nonatomic, retain) UserData* myUser;
UserData.h:
#import <Foundation/Foundation.h>
#interface UserData : NSObject{
NSString* Weight;
NSString* Height;
NSString* GolWeight;
NSString* WeightMeasure;
}
#property (nonatomic, retain) NSString* Weight;
#property (nonatomic, retain) NSString* Height;
#property (nonatomic, retain) NSString* GolWeight;
#property (nonatomic, retain) NSString* WeightMeasure;
#end
UserData.m
#import "UserData.h"
#implementation UserData
#synthesize Weight, Height, GolWeight, WeightMeasure;
-(id)init{
self.Weight = #"0";
self.Height = #"0";
self.GolWeight = #"0";
self.WeightMeasure = #"0";
return self;
}
-(void)dealloc{
[Weight release];
[Height release];
[GolWeight release];
[WeightMeasure release];
[super dealloc];
}
#end
Use valueForKey instead of objectForKey in this line:
[self.myUser setWeightMeasure:[profile objectForKey:#"weight_measure"]];
like this:
[self.myUser setWeightMeasure:[profile valueForKey:#"weight_measure"]];
You might also want to use, since the values could be read as NSNumbers
[self.myUser setWeightMeasure:[[profile valueForKey:#"weight_measure"] stringValue]];
And why do you use strings instead of floats? Wouldn't that make your life easier when you'd need to perform some comparisons?
Also check if you have allocated memory for "myUser", that might be the case as well.
As Eugene mentioned, you should use valueForKey instead of objectForKey
The other thing is you might wanna use property and dot notation whenever you reference your object members, as Apple recommend. It is generally good for you to manage memory.
The previous answer about not initialize your string members in your -init() was totally wrong, if that cause some confusion, I do apologize for it.

Unknown Memory Leak in iPhone

I am currently building an app for the iPhone and cannot figure out why I keep getting a memory leak to appear in the Leaks Instrument tool.
Here is the code and I have added comments to two places of where it is happening.
NSString *pathname = [[NSBundle mainBundle] pathForResource:self.toUseFile ofType:#"txt" inDirectory:#"/"];
//Line below causes a leak
self.rawCrayons = [[NSString stringWithContentsOfFile:pathname encoding:NSUTF8StringEncoding error:nil] componentsSeparatedByString:#"\n"];
self.sectionArray = [NSMutableArray array];
for (int i = 0; i < 26; i++) [self.sectionArray addObject:[NSMutableArray array]];
for(int i=0; i<self.rawCrayons.count; i++)
{
self.string = [self.rawCrayons objectAtIndex:i];
NSUInteger firstLetter = [ALPHA rangeOfString:[string substringToIndex:1]].location;
if (firstLetter != NSNotFound)
{
NSInteger audio = AUDIONUM(self.string);
NSInteger pictures = PICTURESNUM(self.string);
NSInteger videos = VIDEOSNUM(self.string);
//Line below causes a leak
[[self.sectionArray objectAtIndex:firstLetter] addObject:[[Term alloc] initToCall:NAME(self.string):audio:pictures:videos]];
}
[self.string release];
}
Thanks in advance!
Edit
Here are my property declarations.
#property (nonatomic, retain) NSArray *filteredArray;
#property (nonatomic, retain) NSMutableArray *sectionArray;
#property (nonatomic, retain) UISearchBar *searchBar;
#property (nonatomic, retain) UISearchDisplayController *searchDC;
#property (nonatomic, retain) NSString *toUseFile;
#property (nonatomic, retain) NSArray *rawCrayons;
#property (nonatomic, retain) NSString *string;
#property (nonatomic, retain) TermViewController *childController;
Here are the leaks that are occurring after follow Nick Weaver's fixes.
Here is an expanded version of one of the NSCFString.
And another image.
Image with the Responsible Caller:
Also, because this may be useful, here are the properties for Term:
#property (nonatomic, retain) NSString *name;
#property (nonatomic) NSInteger numberAudio;
#property (nonatomic) NSInteger numberPictures;
#property (nonatomic) NSInteger numberVideos;
And the implementation:
#implementation Term
#synthesize name, numberAudio, numberPictures, numberVideos;
- (Term*)initToCall:(NSString*) toSetName:(NSInteger) audio:(NSInteger) pictures:(NSInteger) videos
{
self.name = [toSetName retain];
self.numberAudio = audio;
self.numberPictures = pictures;
self.numberVideos = videos;
return self;
}
- (NSString*)getName
{
return [[name retain] autorelease];
}
-(void)dealloc
{
[name release];
[super dealloc];
}
#end
Ok, try this changed Version of Temp. I've deleted the getter because you have already one by synthesizing. You cann use the getter like this for name:
term.name
The problem was how you set the name: you want a copy of the name and setting it with the synthesized setter without calling a retain should do the trick. You could, of course, have set it with the retained property of name but you should have left out retain, like this self.name = toSetName;. The setter will retain it for you.
#property (nonatomic, copy) NSString *name;
#property (nonatomic) NSInteger numberAudio;
#property (nonatomic) NSInteger numberPictures;
#property (nonatomic) NSInteger numberVideos;
#implementation Term
#synthesize name, numberAudio, numberPictures, numberVideos;
- (Term*)initToCall:(NSString*) toSetName:(NSInteger) audio:(NSInteger) pictures:(NSInteger) videos
{
self.name = toSetName;
self.numberAudio = audio;
self.numberPictures = pictures;
self.numberVideos = videos;
return self;
}
-(void)dealloc
{
[name release];
[super dealloc];
}
Adding an object to an array will retain the instance, so the retain is 2 because you call
[[Term alloc] initToCall..
Do something like
Term *term = [[Term alloc] initToCall..];
[theArray addObject:term];
[term release];
1. See the arrow in the first line in the address column? Click it!
2. After clicking :)
Hard to tell you why the first one is leaking, because we don't know what the property is declared as. Is it retain? copy? assign? what?
The last one is fairly self explanatory though, you're taking ownership of a Term object, and not releasing it when it's added. addObject: retains its argument, meaning if you don't need that Term anymore, you need to give up ownership. I.e., pass -autorelease to the result of your initToCall:::: (which btw is a very bad name for a method)
Change:
[[self.sectionArray objectAtIndex:firstLetter] addObject:[[Term alloc] initToCall:NAME(self.string):audio:pictures:videos]];
to:
Term *tempTerm = [[Term alloc] initToCall:NAME(self.string):audio:pictures:videos];
[[self.sectionArray objectAtIndex:firstLetter] addObject:tempTerm];
[tempTerm release];
By alloc'ing an object you are responsible for it's release.