Not creating a new instance of NSMutableDictionary when passing to another class - ios

i have an NSMutableDictionary declared in a class but i want to print get access to the contents of it in another class for example
#interface MyClass0 : NSObject
{
}
#property (nonatomic, strong) NSMutableDictionary *valuee;
#end
and in implementation i do
#implementation MyClass0
- (void)viewDidLoad{
[super viewDidLoad];
[valuee setObject:#"name" forKey:#"Aryan"];
}
#end
Now i create a new class called MyClass1 where i want to access these
#interface MyClass1 : NSObject
{
}
#property (nonatomic, strong) NSMutableDictionary *dict;
#end
and the implementation
#implementation MyClass1
#synthesize dict;
- (void)viewDidLoad{
[super viewDidLoad];
self.dict = [[NSMutableDictionary alloc] init];
MyClass0 *c = [[MyClass0 alloc] init];
self.dict = c.valuee;
// dict is not nil but the contents inside is nil so it clearly creates a new instance
}
#end

You are creating the instance of MyClass0 and valuee is declared but not initialized.
The closest solution to your code is
MyClass0 *c = [[MyClass0 alloc] init];
c.valuee = [[NSMutableDictionary alloc] init];
self.dict = c.valuee;
If a value is assigned to a declared property then an explicit initialization is not necessary.

If it's just a simple NSMutableDictionary that has the same contents every time you can create a class method in MyClass0 like so:
+ (NSMutableDictionary *) getDict {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:#"name" forKey:#"Aryan"];//did you mean [dict setObject:#"Aryan" forKey:#"name"]?
return dict;
}
To access this, declare the method in the MyClass0.h file like so: + (NSMutableDictionary *) getDict; and simply call [MyClass0 getDict]; in your MyClass1.m file.
If it doesn't have the same contents every time, you'll have to pass the dictionary forward to each view controller in prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Make sure your segue name in storyboard is the same as this next line
if ([[segue identifier] isEqualToString:#"MySegue"]) {
MyClass1 *mc = [segue destinationViewController];
mc.dict = self.valuee;
}
}

Related

Can't add object to NSMutableArray from another class

I am trying to add objects to a NSMutableArray from another class and it won't work. It works perfectly for the other attribute.
I looked at similar questions but couldn't find a suitable answer.
The object iPack :
#interface IPack : NSObject
#property float price;
#property NSMutableArray *cocktails;
#end
In the class of my collection view :
- (void)viewDidLoad {
[super viewDidLoad];
self.iPack = [[IPack alloc] init];
self.iPack.cocktails = [[NSMutableArray alloc] init];
In the class of my cell :
self.collectionView.iPack.price = self.price //perfectly works
NSArray* cock = [NSArray arrayWithObjects:c1,c2,c3,c4,c5, nil];
[self.collectionView.iPack.cocktails addObjectsFromArray:cock]; //line won't work
You haven't shown the [IPack init] method, but I strongly suspect you are not allocating the cocktails array. Simply defining it as a property does not mean it's automatically allocated:
#implementation IPack
- (instancetype)init
{
self = [super init];
if (self) {
_price = 0.0f;
_cocktails = [NSMutableArray new];
}
return self;
}
#end
EDIT
I've just seen this line in your question:
self.iPack.cocktails = [[NSMutableArray alloc] init];
Which would suggest my answer is wrong (despite it being the better way of doing the same thing). Sorry about that; I cannot see why your code doesn't work. Are you sure you are checking correctly?
try this,
in IPack class add a method
#interface IPack : NSObject
#property float price;
#property NSMutableArray *cocktails;
- (instancetype)initWithPrice:(float)price cocktails:(NSMutableArray *)cocktails;
#end
and in implementation
#implementtion IPack
- (instancetype)initWithPrice:(float)price cocktails:(NSMutableArray *)cocktails {
self = [super init];
if (self) {
self.price = price;
self.cocktails = cocktails;
}
}
#end
In the class of my collection view :
remove alloc init in viewDidLoad
that is remove the following lines
self.iPack = [[IPack alloc] init];
self.iPack.cocktails = [[NSMutableArray alloc] init];
In the class of my cell :
NSArray* cock = [NSArray arrayWithObjects:c1,c2,c3,c4,c5, nil];
IPack *ipack = [[IPack alloc] initWithPrice:self.price cocktails:[NSMutableArray arrayArray:cock]];
self.collectionView.iPack = ipack;

Can't add object to NSMutableArray in singleton

I made a singleton and i'm trying to add objects to self.timelineArray but i can't. When i do this i have 9 objects:
NSNumber* nmb = [[NSNumber alloc] initWithInt:1];
[self.dataManager.timelineArray addObject:nmb];
After i insert the nmb object, i still have 9 objects.
Here's my singleton header (only important bits):
#interface DataManager : NSObject
#property (nonatomic, strong) NSMutableArray* timelineArray;
Here's my singleton implementation (only important bits):
#import "DataManager.h"
static DataManager* sharedInstance = nil;
#implementation DataManager
+ (DataManager *) sharedInstance{
#synchronized(self)
{
if (sharedInstance == nil)
sharedInstance = [[self alloc] init];
}
return sharedInstance;
}
- (id)init {
if (self = [super init])
{
self.timelineArray = [[NSMutableArray alloc] init];
}
return self;
}
This is just simple coding and i can't seem to figure out why it does not work.
Trying to modify immutable array(NSArray) will lead to this.
Replace
[responseObject objectForKey:#"timeline"] with [[NSMutableArray alloc] initWithArray:[responseObject objectForKey:#"timeline"]
This was based on the comments of the question.
i'll suggest you to add like following
NSNumber* nmb = [[NSNumber alloc] initWithInt:1];
[[DataManager sharedInstance]timelineArray addObject:nmb];
this will always add into the singleton not the instance of singleton

Trouble setting an NSMutableDictionary inside of another NSMutableDictionary

I need to take information submitted by a user, store that information in an NSMutableDictionary, then store that NSMutableDictionary inside another NSMutableDictionary which is then encoded inside another class. For whatever reason, I can't seem to store the first NSMutableDictionary inside of the other.
I had to slim down the code that's in here due to work rules, so sorry if it seems to be missing anything. I only posted the parts that I'm having trouble with.
UserInfo.h:
#import <Foundation/Foundation.h>
#interface MyPlanInfo : NSObject <NSCoding>
#property (nonatomic, strong) NSMutableDictionary *emergencyDictionary;
#end
UserInfo.m:
#import <Foundation/Foundation.h>
#import "MyPlanInfo.h"
static NSString *emergencyDictionaryKey = #"emergencyDictionaryKey";
#implementation MyPlanInfo
#synthesize emergencyDictionary;
- (id) initWithCoder:(NSCoder *)coder
{
self = [super init];
self.emergencyDictionary = [coder decodeObjectForKey:emergencyDictionaryKey];
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeObject:self.emergencyDictionary forKey:emergencyDictionaryKey];
}
#end
infoView.h
#import <UIKit/UIKit.h>
#import "MyPlanInfo.h"
#interface infoView : UIViewController <NSCoding>
{
NSMutableDictionary *emergencyContactInfo;
NSArray *userInfo;
NSArray *userKeys;
NSMutableArray *tempArray;
}
#property (nonatomic, strong) MyPlanInfo *myPlanInfoObject;
-(void)saveUserInfo;
-(void)loadUserInfo;
#end
infoView.m:
#import "infoView.h"
#interface infoView ()
#end
#implementation infoView
static NSString *userInfoKey = #"userInfoKey";
static NSString *userName;
-(void)viewDidLoad
{
[super viewDidLoad];
if(!self.myPlanInfoObject)
{
self.myPlanInfoObject = [[MyPlanInfo alloc] init];
}
[self loadUserInfo];
}
-(void)addToDictionary
{
emergencyContactInfo = [NSMutableDictionary dictionaryWithObjects:userInfo forKeys:userKeys];
if([userInfo count] != 0 || userInfo == nil)
{
self.myPlanInfoObject.emergencyDictionary = [NSMutableDictionary dictionaryWithObject:emergencyContactInfo forKey:userName];
}
[self saveUserInfo];
}
- (void)saveUserInfo
{
NSData *userInfoData = [NSKeyedArchiver archivedDataWithRootObject:self.myPlanInfoObject];
[[NSUserDefaults standardUserDefaults] setObject:userInfoData forKey:userInfoKey];
}
- (void)loadUserInfo
{
NSData *userInfoData = [[NSUserDefaults standardUserDefaults] objectForKey:userInfoKey];
if(userInfoData)
{
self.myPlanInfoObject = [NSKeyedUnarchiver unarchiveObjectWithData:userInfoData];
}
}
#end
In infoView.m, in the addToDictionary method, userInfo is an array of user inputted information, and userKey's is an array of key's. The emergencyContactInfo NSMutableDictionary works just fine, everything is in it, but when I try to set that as an object in a new NSMutableDictionary, for a key, it doesn't work. Everything is nil.
Anyone have any ideas on how what I'm doing wrong?
Edit: If you down vote, please leave a reason as to why so that I can avoid doing whatever I did wrong in the future.
In the following line you’re creating an instance of MyPlanInfo using plain alloc/init:
self.myPlanInfoObject = [[MyPlanInfo alloc] init];
However, at least in the code provided, you haven’t overridden init in MyPlanInfo, but instead, initWithCoder::
- (id) initWithCoder:(NSCoder *)coder
{
self = [super init];
self.emergencyDictionary = [coder decodeObjectForKey:emergencyDictionaryKey];
return self;
}
When you use just plain init, the MyPlanInfo’s emergencyDictionary instance variable will be nil. You should likely add something like the following to MyPlanInfo to override init:
- (id) init
{
if ((self = [super init])) {
emergencyDictionary = [[NSMutableDictionary alloc] init];
}
return self;
}
That will assure that the newly created MyPlanInfo instance has a proper NSMutableDictionary that can be manipulated from other classes.

How to create an array outside of a function, and be able to add to it in other functions

It seems if I do something like:
NSMutableArray *randomSelection = [[NSMutableArray alloc] init];
Then this needs to be in a function, and I can't modify it later using a different function.
I tried just instantiating it in the .h file,
#interface ViewController:
{
NSMutableArray *Values;
}
But then when I try to append to it during runtime, nothing happens. I try to append to it with this:
int intRSSI = [RSSI intValue];
NSString* myRSSI = [#(intRSSI) stringValue];
[Values addObject:myRSSI];
But the array remains empty when I do this.
How can I fix this?
The recommended way is to create a property;
// ViewController.h
#interface ViewController : UIViewController
{
}
#property (nonatomic, strong) NSMutableArray *values;
#end
Then override the getter for that property, to lazy-initialize it, i.e. the array will be allocated and initialized on first call of the NSMutableArray property's getter:
// ViewController.m
#interface ViewController ()
#end
#implementation ViewController
- (NSMutableArray *)values
{
if (!_values) {
_values = [[NSMutableArray alloc] init];
}
return _values;
}
- (void)viewDidLoad
{
[super viewDidLoad];
//int intRSSI = [RSSI intValue];
//NSString *myRSSI = [#(intRSSI) stringValue];
//[self.values addObject:myRSSI];
// Keep it simple:
[self.values addObject:RSSI];
}
#end

ios error terminating -[__NSArrayM setRoleHistorys:]:

Im trying to make user role page that get data from login. I created the own delegate function to call the webservice but app getting crash due to-[__NSArrayM setRoleHistorys:]: unrecognized selector sent to instance.
Here is my code: in .m file :
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
nodeContent = [[NSMutableString alloc]init];
}
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
arrayitems = [[NSMutableArray alloc] init];
U serRoleDataParser *userroleParser = [[UserRoleDataParser alloc] init];
// UserRole *currentStudent = (UserRole *) arrayitems;
NSString *Username = username.text;
NSLog(#"the String value%#",Username);
[userroleParser getUserHistoryForIndex:0 LoginId:username.text];
NSLog(#"the String user value %#",username.text);
userroleParser.delegate = self;
}
- (void) didrecieveData : (NSArray *) userHistories forIndex :(int) index
{
arrayitems = [[NSMutableArray alloc] init];
UserRole *roles = (UserRole *) arrayitems;
roles.RoleHistorys = userHistories;
datadisplay.text = roles.role;
NSLog(#"the Success data%#", datadisplay.text);
}
in delegate file .h
#interface UserRole : NSObject
#property (nonatomic,copy) NSString *username;
#property (nonatomic,copy) NSString *role;
#property (nonatomic,copy) NSString *empcode;
#property (nonatomic,copy)NSMutableArray * RoleHistorys;
#end
Dataparser.h file (delegate)
#import <Foundation/Foundation.h>
#import "UserRole.h"
#protocol UserRoleDataParserDelegate <NSObject>
- (void) didrecieveData : (NSArray *) userHistories forIndex :(int) index ;
#end
#interface UserRoleDataParser : NSObject<NSXMLParserDelegate>
{
NSMutableData *xmlData;
NSXMLParser *userroleParser;
NSMutableString *capturedString;
BOOL captureCharacters;
NSMutableArray *userHistories;
}
- (void) getUserHistoryForIndex : (int) index LoginId :(NSString*) loginId;
#property (weak,nonatomic) id <UserRoleDataParserDelegate> delegate;
#property (nonatomic) int index;
#end
am getting output in nslog but the app getting crash.
This code isn't correct:
arrayitems = [[NSMutableArray alloc] init];
UserRole *roles = (UserRole *) arrayitems;
You can't just cast an array to your custom class type (unless you have subclassed NSMutableArray and the instance is actually of the subclass type). You need to create an instance of or find the correct instance you want before you try to use it.
You create NSMutableArray and you cast it to UserRole object, after that you try to save data in that: roles.RoleHistorys :
arrayitems = [[NSMutableArray alloc] init];
UserRole *roles = (UserRole *) arrayitems;
roles.RoleHistorys = userHistories; //<- Error happened here
So you try to save data by calling selector setRoleHistorys on object of type NSMutableArray which you cannot do because NSMutableArray doesn't contain that property.

Resources