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.
Related
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;
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
I have the following snippet and a call to the method is not working!
#interface myVM(){
NSArray *results;
}
#property (nonatomic, strong) MyModel *model;
#end
#implementation myVM
- (instancetype)initWithItems{
self = [super init];
if (!self) return nil;
**[self.model loadInfo];**
_DeviceNameArray = self.model.DeviceNames;
}
What is the reason for the method being not called?
You have to allocate and initialize it first:
- (instancetype)initWithItems{
self = [super init];
if (!self) return nil;
self.model = [MyModel new]; // like this
[self.model loadInfo];
_DeviceNameArray = self.model.DeviceNames;
return self;
}
self.model is not initialized. If you debug it, you will see it is nil.
By the time you are calling [self.model loadInfo];, the model property has not been set yet and is nil. You probably want something like:
- (instancetype)initWithModel:(MyModel *)aModel {
self = [super init];
if (!self) return nil;
self.model = aModel;
[self.model loadInfo];
_DeviceNameArray = self.model.DeviceNames;
return self;
}
You should structure your custom init methods like this for better readability.
- (instancetype)initWithItems
{
self = [super init];
if (self) {
[self.model loadInfo];
_DeviceNameArray = self.model.DeviceNames;
}
return self;
}
The problem is that self.model has not been initialised anywhere. It is just a property that contains no information - it is nil. You need to assign something to it somewhere.
E.g., pass a model object as parameter like so, initWithItem:(MyModel *)model, then assign it to self.model.
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
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