So I know my problem is that my transfer array is not being initialized correctly. Where should I put transfer = [[NSMutableArray alloc] init];?
#interface PictureViewController (){
Poi *labelPoi;
}
#end
#implementation PictureViewController
#synthesize imageX;
#synthesize imageY;
#synthesize name;
#synthesize transfer;
- (id)init
{
self = [super init];
if(self) {
transfer = [[NSMutableArray alloc] init];
}
return self;
}
-(id)initWithLabel:(double)imageX andY:(double)imageY withName:(NSString *)name{
self = [super init];
if(self){
// transfer = [[NSMutableArray alloc] init];
self.imageX = imageX;
self.imageY = imageY;
self.name = name;
}
return self;
}
/*-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self){
transfer = [[NSMutableArray alloc] init];
self.imageX = imageX;
self.imageY = imageY;
self.name = name;
NSLog(#"imageX: %f", self.imageX);
NSLog(#"imageY: %f", imageY);
NSLog(#"name: %#", name);
}
return self;
}*/
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
NSLog(#"transfer count: %lu",(unsigned long)transfer.count);
for(int i = 0; i < transfer.count; i++){
UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake([[transfer objectAtIndex:i] imageLocationX], [[transfer objectAtIndex:i] imageLocationY], 200, 50)];
label.text = [[transfer objectAtIndex:i] name];
label.font = [UIFont systemFontOfSize:14];
label.backgroundColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0];
[self.view addSubview:label];
NSLog(#"asdfasdsd");
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (id)display:(double)imageXX andY:(double)imageYY withName:(NSString *)namee{
NSLog(#"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
NSLog(#"imageX: %f",imageXX);
NSLog(#"imageY: %f", imageYY);
NSLog(#"name: %#", namee);
labelPoi = [[Poi alloc] init];
//transfer = [[NSMutableArray alloc] init];
labelPoi.imageLocationX = imageXX;
labelPoi.imageLocationY = imageYY;
labelPoi.name = namee;
[transfer addObject:labelPoi];
NSLog(#"label.x: %f should be: %f", labelPoi.imageLocationX, imageXX);
NSLog(#"label.y: %f should be: %f", labelPoi.imageLocationY, imageYY);
NSLog(#"label.name: %# should be: %#",labelPoi.name,namee);
NSLog(#"transssssfer: %lu", (unsigned long)transfer.count);
NSLog(#"asfddfsaasfdfdsfsd %f", [[transfer objectAtIndex:0] imageLocationX]);
return self;
}
#end
The Poi object is made up of an imageLocationX, imageLocationY, and name and I am trying to put the Poi object into an array named transfer however, whenever I try to access transfer elements, I receive 0 or null. The (id)display function is being called several times from a different view NSMutable alloc in that function, the array gets reset.
Here is the output:
2013-07-19 11:22:06.736 AR_UAV_App[12466:11303] %%%%%%%%%%%%%%%%%%%%%%%%
2013-07-19 11:22:06.736 AR_UAV_App[12466:11303] imageX: 224.485718
2013-07-19 11:22:06.736 AR_UAV_App[12466:11303] imageY: 116.353401
2013-07-19 11:22:06.736 AR_UAV_App[12466:11303] name: Beutel Student Health Center
2013-07-19 11:22:06.736 AR_UAV_App[12466:11303] label.x: 224.485718 should be: 224.485718
2013-07-19 11:22:06.736 AR_UAV_App[12466:11303] label.y: 116.353401 should be: 116.353401
2013-07-19 11:22:06.736 AR_UAV_App[12466:11303] label.name: Beutel Student Health Center should be: Beutel Student Health Center
2013-07-19 11:22:06.737 AR_UAV_App[12466:11303] transssssfer: 0
2013-07-19 11:22:06.737 AR_UAV_App[12466:11303] asfddfsaasfdfdsfsd 0.000000
2013-07-19 11:22:06.737 AR_UAV_App[12466:11303] #############################################################
EDIT: .h file
#interface PictureViewController : UIViewController{
NSMutableArray *transfer;
}
#property (nonatomic) double imageX;
#property (nonatomic) double imageY;
#property (nonatomic) NSString *name;
#property (nonatomic,retain) NSArray *transfer;
- (IBAction)backView:(id)sender;
- (IBAction)load:(id)sender X:(double)imageX andY:(double)imageY withName:(NSString *)name;
-(id)initWithLabel:(double)imageX andY:(double)imageY withName:(NSString *)name;
-(id)display:(double)imageX andY:(double)imageY withName:(NSString *)name;
#end
This init method should become the "designated" initializer:
-(id)initWithLabel:andY:withName:(NSString *)name
(by the way, it's not named correctly according the naming conventions)
The designated initializer shall initialize the instance properly (that is, in your case it may initialize the array transfer, unless you use a lazy accessor ).
The "designated initializer" is most often the "most specialized" initializer - that is, that one with the most parameters. Most often, there is only one and easily identifiable designated initializer.
The "designated initializer" has the canonical form:
-(id)initWithLabel:(double)imageX andY:(double)imageY withName:(NSString *)name{
self = [super init];
if(self){
// initialization
...
}
}
Other init methods like the init method shall invoke the designated initializer like:
- (id)init {
return [self initWithLabel:0 andY:0 withName:#""];
}
I guess one problem can be that when you are creating this controller you are calling to:
-(id)initWithLabel:(double)imageX andY:(double)imageY withName:(NSString *)name
In case you do that, you are calling to [super init] what will never go through the init method of your class (where you allocated the array). In case you have different methods to init a controller I recommend you to have a:
commonInit{
_transfer = [[NSMutableArray] alloc] init];
}
Then call this method for every init method that you have in your controller so you ensure that array is allocated.
Other thing is just allocate your array in the viewDidLoad of your controller.
Just for making know, you can "allocated" an array without having to take care about release the object by calling to [NSMutableArray arrayWithCapacity:0];
Are you initializing your PictureViewController with -(id)initWithLabel:(double)imageX andY:(double)imageY withName:(NSString *)name? If so, I can tell you what the problem is...
-(id)initWithLabel:(double)imageX andY:(double)imageY withName:(NSString *)name
{
self = [super init]; // <--- You are likely confused about this line
.....
}
[super init] does not pass a message to your custom -(id)init method. It instead is referring to PictureViewController's superclass, which is likely UIViewController.
Your problem should be fixed by uncommenting transfer = [[NSMutableArray alloc] init]; in the initWithLabel: custom init method.
make a property (synthesize it #synthesize transfer=_transfer;), use lazy instantiation like:
-(NSMutableArray*)transfer
{
if (!_transfer)
{
_transfer=[NSMutableArray array];
}
return _transfer;
}
and take it out of your init
Related
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.
I have created a few buttons and labels using storyboard in XCode 4.6.3
I want to fire some methods on the click of the buttons placed in the FirstViewController and for the methods to work I have defined some variables/NSMutableArrays (currentQuestionIndex,questions,etc.). I want to use a custom init method for inititalizing these.
When I leave initWithNibName and initWithCoder as it is and write a new init method and write my implementation in it, it doesn't get called.
But when I manipulated the code as I have shown in the snippets below, it worked.
I want to know how to use custom init methods when creating objects using Storyboard because what I did here is probably not a good practice. When I tried initializing using initWithCoder , it did not work. But from what I can recall, we use initWithCoder to initialize from Storyboard, right?
The buttons/labels in the storyboard are in FirstViewController.
This is my FirstViewController.h file
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController
{
int currentQuestionIndex;
// The model objects
NSMutableArray *questions;
NSMutableArray *answers;
//The view objects
IBOutlet UILabel *questionField;
IBOutlet UILabel *answerField;
}
#property (strong, nonatomic) UIWindow *window;
- (IBAction)showQuestion:(id)sender;
- (IBAction)showAnswer:(id)sender;
#end
and
This is my FirstViewController.m file
#import "FirstViewController.h"
#interface FirstViewController ()
#end
#implementation FirstViewController
- (id)init {
// Call the init method implemented by the superclass
self = [super init];
if(self) {
currentQuestionIndex = -1;
// Create two arrays and make the pointers point to them
questions = [[NSMutableArray alloc] init];
answers = [[NSMutableArray alloc] init];
// Add questions and answers to the arrays
[questions addObject:#"What is 7 + 7?"];
[answers addObject:#"14"];
[questions addObject:#"What is the capital of Vermont?"];
[answers addObject:#"Montpelier"];
[questions addObject:#"From what is cognac made?"];
[answers addObject:#"Grapes"];
}
// Return the address of the new object
return self;
}
-(IBAction)showQuestion:(id)sender
{
currentQuestionIndex++;
if(currentQuestionIndex == [questions count])
currentQuestionIndex = 0;
NSLog(#"%d",[questions count]);
NSString *question = [questions objectAtIndex:currentQuestionIndex];
NSLog(#"dislaying question at index %d : %#" ,currentQuestionIndex,question);
[questionField setText:question];
[answerField setText:#"???"];
}
-(IBAction)showAnswer:(id)sender
{
NSString *answer = [answers objectAtIndex:currentQuestionIndex];
[answerField setText:answer];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
i ma getting all the values..when I log...try this
-(id)initWithCoder:(NSCoder *)aDecoder{
if(self = [super initWithCoder:aDecoder]) {
currentQuestionIndex = 15;
NSLog(#"%d", currentQuestionIndex);
// Create two arrays and make the pointers point to them
questions = [[NSMutableArray alloc] init];
answers = [[NSMutableArray alloc] init];
// Add questions and answers to the arrays
[questions addObject:#"What is 7 + 7?"];
[answers addObject:#"14"];
[questions addObject:#"What is the capital of Vermont?"];
[answers addObject:#"Montpelier"];
[questions addObject:#"From what is cognac made?"];
[answers addObject:#"Grapes"];
NSLog(#"Questions = %#", questions);
NSLog(#"Answers = %#", answers);
}
return self;
}
you can use - (void)awakeFromNib method in your UIViewController
I have a #property (nonatomic,retain) NSMutableArray *transfer_array; in .h file and in my .m I have
#synthesize transfer_array = _transfer_array;
- (id)init
{
self = [super init];
if(self) {
self.transfer_array = [[NSMutableArray alloc] init];
}
return self;
}
and I add objects to the array in this function
- (id)display:(double)imageXX andY:(double)imageYY withName:(NSString *)namee{
//if((self == [super init])){
NSLog(#"````````````````````````````````````````````````````````");
NSLog(#"imageX: %f",imageXX);
NSLog(#"imageY: %f", imageYY);
NSLog(#"name: %#", namee);
labelPoi = [[Poi alloc] init];
labelPoi.imageLocationX = imageXX;
labelPoi.imageLocationY = imageYY;
labelPoi.name = namee;
[self.transfer_array addObject:labelPoi];
The objects add successfully bu whenever I try to access the array elements in another instance such as:
- (void)viewDidLoad{
[super viewDidLoad];
NSLog(#"transfer_array count: %lu",(unsigned long)self.transfer_array.count);
Then the array is empty.
Any help would be appreciated!
Instances are independent objects. Changing the internal state of one doesn't affect the internal state of others.
I am using an NSData to store an object for later use. It has quite a few NSStrings and I need to pull it out of an object.
For some reason, only some of the NSStrings are stored and some others get zeroed out!
I was thinking it must be something with my code, that I must have forgotten to initialize some string, but for a very weird reason some of the strings lose the data!
I can't get theImportantString to get it's relevant value because it first seems like the variable got it's value, but after coming back from Unarchive, it's equal to #""!
// CMyData.h
/////////////////////
#interface CMyData : NSObject <NSCoding>
{
NSString *ID;
NSString *DIST;
.
.
}
#property (nonatomic,retain) NSString *ID;
#property (nonatomic,retain) NSString *DIST;
#end
// CMyData.m
//////////////////////
#import "CMyData.h"
#implementation CMyData
#synthesize ID;
#synthesize DIST;
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.ID = [decoder decodeObjectForKey:#"ID"];
self.DIST = [decoder decodeObjectForKey:#"DIST"];
.
.
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:ID forKey:#"ID"];
[encoder encodeObject:DIST forKey:#"DIST"];
.
.
}
- (void)dealloc {
[ID release];
[DIST release];
[super dealloc];
}
#end
MyController.m
-(void) makeObject: (NSDictionary *)dict
{
CMyData* myData=[[CMyData alloc] init];
myData.ID = [[NSString alloc] initWithString:[dict objectForKey:#"NAME"]];
myData.DIST = [[NSString alloc] initWithString:[dict objectForKey:#"DISTRIBUTOR"]];
.
.
myObject = [[[MYObject alloc] init];
myObject.data = [NSKeyedArchiver archivedDataWithRootObject:myData];
}
And then a tap on a button happens:
- (void) tapOnIcon: (MyObject*)theObject
{
CMyData *data = [NSKeyedUnarchiver unarchiveObjectWithData:theObject.data];
[delegate showData:data];
}
in the delegate Controller (Where the value can't be set anymore):
delegateController.m
/////////////////////////////////
-(void) showData:(CMyData*)theData{
self.theImportantString = [[NSString alloc] initWithString:theData.DIST];
.
.
.
}
Seems you have types mismatch:
// in - (id)initWithCoder:(NSCoder *)decoder
self.DIST = [decoder decodeIntForKey:#"DIST"];
but in declaration you have
// in CMyData.h
NSString *DIST;
This should be:
// in - (id)initWithCoder:(NSCoder *)decoder
self.DIST = [NSString stringWithFormat:#"%d", [decoder decodeIntForKey:#"DIST"]];
I am trying to create a NSMutableDictionary in my class. I have read many post in stackoverflow to understand the difference. But now i am totally confused. So any one correct me , which one is the correct way of initialing a NSMutableDictionary in my class . I have to access this dictiionary in many areas of my application .So suggest me the good way of using the variable initialization ...
/// .h file
#interface ActiveFeeds : NSObject {
}
#property (nonatomic, copy) NSMutableDictionary *invDictionary;
#property (nonatomic, retain) NSString *filePath;
#end
#implementation ActiveFeeds
#synthesize filePath;
#synthesize invDictionary;
- (id)init{
self = [super init];
if (self != nil){
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:self.filePath];
self.invDictionary = [dictionary mutableCopy];
dictionary release];
}
return self;
}
/* And use self.invDictionary all in the application */
- (void)setObjectAtKey:(NSMutableDictionary *)objectDic atKey:(NSString *)setKey{
[self.invDictionary setObject:objectDic forKey:setKey];
}
- (void)dealloc {
[self.invDictionary release];
[self.filePath release];
[super dealloc];
}
#end
or like this ....
#interface ActiveFeeds : NSObject {
NSMutableDictionary *invDictionary;
NSString *filePath;
}
#end
#implementation ActiveFeeds
- (id)init{
self = [super init];
if (self != nil){
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath];
invDictionary = [dictionary mutableCopy];
[dictionary release];
}
}
return self;
}
/* And use invDictionary all in the application */
- (void)setObjectAtKey:(NSMutableDictionary *)objectDic atKey:(NSString *)setKey{
[invDictionary setObject:objectDic forKey:setKey];
}
- (void)dealloc {
[invDictionary release];
[filePath release];
[super dealloc];
}
#end
Please any one help me to get the correct way of using the variables ....
- (id)initWithFilePath:(NSString *)path{
self = [super init];
if (self != nil){
self.filePath = path;
self.invDictionary = [NSMutableDictionary dictionaryWithContentsOfFile:path];
}
return self;
}
also
- (void)dealloc {
[invDictionary release];
[filePath release];
[super dealloc];
}