I simply want to access a NSString from my first class in my second class.
I used properties in my first class and this:
NSLog(#"The text is: %#", self.fileText);
returns the correct string in my first class.
But in my second class, this:
FirstViewController* controller = [[FirstViewController alloc] init];
NSLog(#"text: %#", controller.fileText);
returns (null).
I imported the class correctly.
What could I have done wrong?
Use this
//in your first class
NSUserDefaults *strinToSave= [NSUserDefaults standardUserDefaults];
[strinToSave setObject:self.fileText forKey:#"filTextString"];
and to retrieve saved data in the second class, use this:
NSString *yourString=[[NSUserDefaults standardUserDefaults] valueForKey:#"filTextString"];
//use yourString however you want
NSLog(#"%#",yourString);
Considering the second class is either a sub-class of the first class or jus an instance of the class (which seems more likely).
Be sure what you are doing in your init block of the FirstViewController, because that's all that's being called for the second implementation and if you have not initialized your string there, the value will be null. So yep, check there.
Related
I have a part in my code that calls a method on a different class.
The different class is a singleton.
I didn't have any issues with this class until today, everything worked properly. I don't know why, but after a few insignificant changes i've made today, the code seems to ignore some of my code. It seems that everything is ok and it passes through all the lines but if i put a breakpoint inside one of the methods in my singleton class, it doesn't stop. It just doesn't call those methods.
Does anyone has an idea why could that be?
I tried cleaning the project, tried quitting Xcode, nothing helped so far.
This is an example of how my method in my singleton ".m" looks like:
-(void)setUserCurrentLocationWithLatitude:(NSNumber *)latitude andLongitude:(NSNumber *)longitude andUserIndex:(NSNumber *)userIndex{
NSMutableArray* tempPlayersArray = [NSMutableArray arrayWithArray: [[NSUserDefaults standardUserDefaults] arrayForKey: #"kgpsUsersArray"]];
NSMutableDictionary * userTempDict = [[NSMutableDictionary alloc] initWithDictionary:[tempPlayersArray objectAtIndex:[userIndex integerValue]]];
NSLog(#"latitude = %f",[latitude floatValue]);
[userTempDict setObject:latitude forKey:#"latitude"];
[userTempDict setObject:longitude forKey:#"longitude"];
[defaults setObject:tempPlayersArray forKey:#"kgpsUsersArray"];
[defaults synchronize];
}
And this is how it is defined in ".h" file:
-(void)setUserCurrentLocationWithLatitude:(NSNumber *)latitude andLongitude:(NSNumber *)longitude andUserIndex:(NSNumber *)userIndex;
And in my viewController.m file the singleton is being called initialized like this:
#import "PlayersData.h"
usersData = [PlayersData sharedInstance];
and the method is called like this:
[usersData setUserCurrentLocationWithLatitude:[NSNumber numberWithFloat:32.125493] andLongitude:[NSNumber numberWithFloat:34.858962] andUserIndex:[NSNumber numberWithInt:j]];
Thanks,
It is possible that the singelton was not created. Debug it, to be sure it is not nil.
I have an NSDictionary that I am passing to a NSObject Class where I pull all of the values out of the dictionary and pass them into their correct types.
For instance NSInteger, BOOL, NSString, char are the types of values I am pulling out of the NSDictionary and putting into their only variables.
My question what is the best way to turn these values into one big object that can then be putt into an array?
I have heard that I can use the class itself as an Object.. But I am not really sure how to do this.
or could I just put them back into a NSDictionary?... but if thats the case do NSDictionaries allow for multiple value types?
Actually, you are in the right path. this is basically MVC architecture way. so you are questioning about M = Model.
Model in here example is class that defines all variables. cut to the point, here's you should do:
-> create a class that contain your variable, with #property & #synthesize name : ClassA.
then you could set object ClassA into dictionary.
ClassA *myClass = [[ClassA alloc] init];
myClass.myString = #"test String";
myClass.myBoolean = True;
[dictionary setObject:myClass forKey:#"myObject"];
[myClass release]; //we no longer need the object because already retain in dictionary.
then retrieve it by :
ClassA *myClass = (ClassA*)[dictionary objectForKey:#"myObject"];
NSLog(#"this is value of myString : %# & boolean : %i",myClass.myString,myClass.myBoolean);
You can put the collection of values in NSDictionary, NSArray, NSMutableArray, etc. Any of the collection types. Or if you have a fixed number of values/types, you can create a class that has a data member for each value/type and put it in that. The class solution would eliminate having to do a lot of casting, but it also only works if there are a fixed number of values/types.
Here is the AppleDoc on collections.
Yeah, You can create a class itself with these as different values as a properties.Once you pass this object to any class you can access those values there by obj.propertyName.Doing by this Lead to create Modal in MVC pattern.
Please let me know if there is doubt.
Test *object = [[Test alloc] init];
object.testBool=true;
object.testString=#"Test";
NSDictionary *passData = [[NSDictionary alloc] initWithObjectsAndKeys:object,#"testObject", nil];
Test *getObject = (Test*)[passData objectForKey:#"testObject"];
NSLog(#"%d",getObject.testBool);
NSLog(#"%#",getObject.testString);
You can customized the init method of Test Class.
How can i lazily initialize a NSMutableArray of Buttons ? I do something like this :
-(NSMutableArray *)roasteryButtons
{
if(!roasteryButtons)
{
roasteryButtons = [ NSMutableArray new];
//other code
}
return roasteryButtons;
}
And don't know what to do to call this lazy initializer ? i.e. I need to initialize the array so that i may set the frame for every button in the array
What u have done is correct. Instead of allocating the array in the init method of class, u are allocating the array only when required. Thus it serves the purpose of lazily allocating.
In the class, Wherever you want the array, you just call,
NSMutableArray *arr = [self roasteryButtons];
Also declare the method in header file as, -(NSMutableArray*)roasteryButtons;.
If you want the reference of the array in other classes, the call like,
[classObj roasteryButtons];
I have shown it as instance method. You can also declare that as class method, if you want like that.
And release that in -(void)dealloc method.
I guess you know when to call this method, right ?
The first thing is that you shouldn't use "new" method, but [[NSMutableArray alloc] init] instead : You should have a look at all existing [Init] methods available for NSArray : there are a bunch of them (with capacity, with objects, etc...)
Anyway, you should add some parameters to your method [roasteryButtons] : parameters that will help the method to know, for instance how many buttons to create, what is the frame where they have to show, etc. So this will look a bit like
-(NSMutableArray *)roasteryButtonsWithFrame:(*Frame) andNumbersOfButtons:(int)
for example...
or instead of parameters, you can pass a reference to a delegate that will be able to give answers to those questions (How many buttons, what's my frame and bounds, etc.) So in this case, the method will look like :
-(NSMutableArray *)roasteryButtonsWithDelegate:(id)
(This delegate should implement a protocol that you will create, containing the different methods that the delegate will have to respond to. ie methods like [howManyButtons]...)
The Perfect Way to Lazy initialize is as follow
in .h file declare your NSMUtableArray as property as follow
#property (nonatomic,strong) NSMutableArray *array;
Now in .m file synthesize it and do lazy initialize in getter like as follow:
#synthesize array=_array;
(NSMutableArray *) array
{
(!_array) _array=[[NSMutableArray alloc]init];
//this line is called lazy intialization..this line will create MutableArray at program //run time.
return _array
}
Now answer why we need this is that it take care about that if no NSMutableArray is created then it create it at programme run time and like this your app will not crash.
You could make your method a class method:
+(NSMutableArray *)roasteryButtons {
in this way you will be able to call it like this:
[MyRoasteryButtonClass roasteryButtons];
and this will return you your object.
Hope this helps.
I have a subclass of NSManagedObject Class used with Core Data in iPhone. However, I have a temporary "field" (ivar) that I want to add in that Class (but I dont want to persist it in the data-store). Tried to use informal and formal protocol, but both of them give me a "static-variable" like behaviour. (It behaves like a Class Variable rather than Instance Variable). Any suggestion?
My first attempt, created Test "Dummy-class" which is supposedly a subclass of NSManagedObject, then I created Test-category
#interface Test (custom)
NSString *_string ;
- (void)setString:(NSString *)newString;
- (NSString *)string;
#end
Those are the usual setter and getter. This is the way I use the Test class
Test *a = [[Test alloc] init];
Test *b = [[Test alloc] init];
[a setString:#"Test1"];
NSLog(#"%#", [a string]); //This will print out Test1
[b setString:#"Test2"];
NSLog(#"%#", [b string]); //This will print out Test2
NSLog(#"%#", [a string]); //Unfortunately, this will also print out Test2
I could also mess with the NSManagedObject subclass (which is my Entity) directly but I dont think that is the way to do it.
You can't add an instance variable in the (in)formal protocol or in the category.
Any variable definition inside the category is treated as a variable definition at the file level outside the category, so it behaves like a class variable. It's a confusing behavior; I guess the compiler should warn about it.
The standard solution is to add the ivar which holds transient data (which does not persist in the database) in the subclass representing the entity directly, as in:
#interface MyEntity:NSManagedObject{
NSString*stringHoldingTransientSomething;
}
...
#end
and then specifying MyEntity as the class in the Core Data Editor. Note that Core Data does not automatically save ivars in your custom NSManagedObject subclass; it only saves the properties specified in the Core Data model. So you can add as many book-keeping ivars as you want in your custom subclass.
I have a NSXMLParser that parses YT's API. It then turns all the videos into a class I wrote called video. Then the class is put into an array. Then back at my rootviewcontroller I access xmlParser.allVideos (xmlParser is a class I wrote that is the delegate for the xml parser.
Here is what I do with it in the viewDidLoad:
arrayFromXML = xmlParser.allVideos;
Then in the drawing of the tableView I do this:
tempVideo = [arrayFromXML objectAtIndex:indexPath.row];
cell.textLabel.text = tempVideo.videoTitle; //crashes here and says NSString has been deallocated.
How can I fix this?
If arrayFromXML is an instance variable you have to retain or copy (to be safe from later manipulation) the array as xmlParser simply might not be alive anymore when other methods are called later:
arrayFromXML = [xmlParser.allVideos copy];
Or better yet using a copy or retain property:
self.arrayFromXML = xmlParser.allVideos;