Short background: I am creating an app in which the user can see the menus for each restaurant. I have created a class called "Dish" in which the name, ingredients and price of a menu item is set. I have then created a class for each restaurant which creates and stores the items for each restaurant. I want the UITableView, in which I display the menus, to divide the parts of the menus (for example "main dishes", desserts") into the table sections.
Ideally, I would create an array with the parts for each restaurant menu, in which a number of array (one for every menu part) containing the dishes in that part. I have tried this, and cannot get it to work. It seems like I cannot pass an array containing an array, since it will only return nil. Is this really the case?
Under is the code for my class containing the menu of the restaurant called Badholmen, which now only contains twi dishes. But other menus I have contain up to 70 dishes and there I need to be able to put every dish in an array, and the [allBadholmen addObject:ArrayOfMenuParts:
#import "BadholmenStore.h"
#import "Dish.h"
#implementation BadholmenStore
+ (BadholmenStore *)sharedStore
{
static BadholmenStore *sharedStore = nil;
if (!sharedStore)
sharedStore = [[super allocWithZone:nil] init];
return sharedStore;
}
#pragma mark - tillägg av platser
- (void)createBadholmen
{
Dish *bhvar = [[Dish alloc] initWithName:#"Varierande meny"
ingredients:#" "
price:#" "];
[allBadholmen addObject:bhvar];
Dish *bhsom = [[Dish alloc] initWithName:#"Sommarlunch med varierande meny (endast sommartid)"
ingredients:#"inkl. måltidsdryck"
price:#"79:-"];
[allBadholmen addObject:bhsom];
}
- (void)emptyArray
{
[allBadholmen removeAllObjects];
}
- (NSArray *)allBadholmen
{
return allBadholmen;
}
#pragma mark - Overriden methods
+ (id)allocWithZone:(NSZone *)zone
{
return [self sharedStore];
}
- (id)init
{
self = [super init];
if (self) {
allBadholmen = [[NSMutableArray alloc] init];
}
return self;
}
#end
To make the table view aware of the dishes in the menu, I call (in the init method of the table view):
[[BadholmenStore sharedStore] emptyArray];
[[BadholmenStore sharedStore] createBadholmen];
Do like this, hope this helps u :)
// in BadholmenStore.h
#import <Foundation/Foundation.h>
#interface BadholmenStore : NSObject
{
NSMutableArray *allBadholmen; //for your shared object contains one "mutable array", define it hear
}
+ (BadholmenStore *)sharedStore; //your class method
//instance methods
- (void)createBadholmen;
- (void)emptyArray;
- (NSMutableArray *)allBadholmen;
#end
// in BadholmenStore.m
#import "BadholmenStore.h"
#import "Dish.h"
#implementation BadholmenStore
static BadholmenStore *sharedStore = nil; //it shoud be visible to all, put this line hear
+ (BadholmenStore *)sharedStore
{
if (!sharedStore)
sharedStore = [[super allocWithZone:nil] init];
return sharedStore;
}
#pragma mark - tillägg av platser
- (void)createBadholmen
{
Dish *bhvar = [[Dish alloc] initWithName:#"Varierande meny"
ingredients:#" "
price:#" "];
[allBadholmen addObject:bhvar];
Dish *bhsom = [[Dish alloc] initWithName:#"Sommarlunch med varierande meny (endast sommartid)" ingredients:#"inkl. måltidsdryck" price:#"79:-"];
[allBadholmen addObject:bhsom];
}
- (void)emptyArray
{
[allBadholmen removeAllObjects];
}
- (NSMutableArray *)allBadholmen // replace your NSArray with NSMutableArray
{
return allBadholmen;
}
#pragma mark - Overriden methods
+ (id)allocWithZone:(NSZone *)zone
{
return [self sharedStore];
}
- (id)init
{
self = [super init];
if (self) {
allBadholmen = [[NSMutableArray alloc] init];
}
return self;
}
#end
//in the class where u are using this shared class object
[super viewDidLoad];
[[BadholmenStore sharedStore] emptyArray];
[[BadholmenStore sharedStore] createBadholmen];
NSMutableArray *allObjects = [[BadholmenStore sharedStore] allBadholmen]; // now use allObjects
Related
Hello I'm junior in Objective-C and Swift programming.
I have NSMutableArray in ExampleMenuViewController.m or(and) SomeClass.m declared as vcTabs.
NSMutableArray *vcTabs;
When I have two declares 'vcTabs' Xcode returns duplicate symbol '_vcTabs' (...)
How to add objects to an existing NSMutableArray init in other class (ExampleMenuViewController.m)?
I need append new objects from another class (SomeClass.m) to vcTabs (NSMutableArray).
I wrote in SomeClass.m this code:
if ([Tools isNonullValueForKey:[dictionary valueForKey:#"additional_tabs"]]) {
additional_tabs = [dictionary valueForKey:#"additional_tabs"];
NSLog(#"additionalTabs count: %lu", [additional_tabs count]);
for (int i = 0; i < [additional_tabs count]; i++) {
if ([Tools isNonullValueForKey:[additional_tabs valueForKey:#"_id"]]) {
additional_tab_id = [[additional_tabs valueForKey:#"_id"] objectAtIndex:i];
}
if ([Tools isNonullValueForKey:[additional_tabs valueForKey:#"names"]]) {
NSDictionary *dic = [[additional_tabs valueForKey:#"names"] objectAtIndex:i];
_en_additional_tab_name = [dic valueForKey:#"en"];
_pl_additional_tab_name = [dic valueForKey:#"pl"];
}
if ([Tools isNonullValueForKey:[additional_tabs valueForKey:#"url"]]) {
additional_tab_url = [[additional_tabs valueForKey:#"url"] objectAtIndex:i];
//NSLog(#"additional_tab_url: %#", _additional_tab_url);
}
[vcTabs addObject:[[VCTab alloc] initWithIdAndTypeAndUrl:additional_tab_id :VCTabAdditional :additional_tab_url]];
NSLog(#"%# %d %# %# %# %#", #"pos", i, #"id: ", additional_tab_id, #"url: ", additional_tab_url);
}
}
ExampleMenuViewController method with initVCTabs
- (void)initVCTabs {
vcTabs = [[NSMutableArray alloc] init];
[vcTabs removeAllObjects];
if ([Tools getBooleanUserDefault:#"example_visible_tab_attendees" :YES]) {
[vcTabs addObject:[[VCTab alloc] initWithType:VCTabAttendees]];
}
(...)
if ([Tools getBooleanUserDefault:#"example_visible_tab_user_info" :YES]) {
[vcTabs addObject:[[VCTab alloc] initWithType:VCTabUserInfo]];
}
if ([Tools getStringUserDefault:#"example_additional_tab_id" :#""]) {
NSString *additionalTabId = [Tools getStringUserDefault:#"conference_additional_tab_id" :#""];
NSString *additionalTabUrl = [Tools getStringUserDefault:#"conference_additional_tab_url" :#""];
NSLog(#"additionalTabId %#", additionalTabId);
NSLog(#"additionalTabUrl %#", additionalTabUrl);
[vcTabs addObject:[[VCTab alloc] initWithIdAndTypeAndUrl:additionalTabId :VCTabAdditional :additionalTabUrl]];
}
}
PS. If I use from ExampleMenuViewController I have only one tab with last object properties... but additional_tabs array have 17 objects.
Do you have any ideas or advices?
All the best for you everyone!
When are you calling initVCTabs?
When / how is the code in SomeClass.m running?
For being a "junior in Objective-C and Swift programming" you seem to have a lot going on that you don't understand yet. Try creating a new project and learn how things work -- then implement that in your full project.
Here is a very, very simple example. With the information you provided in your question, this may or may not relate directly - but it should give you an idea of where to go:
SomeClass.h
// SomeClass.h
// Created by Don Mag on 8/30/20.
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
#interface SomeClass : NSObject
- (void)moreTabs:(NSMutableArray *)a;
#end
NS_ASSUME_NONNULL_END
SomeClass.m
// SomeClass.m
// Created by Don Mag on 8/30/20.
#import "SomeClass.h"
#interface SomeClass()
#end
#implementation SomeClass
- (void)moreTabs:(NSMutableArray *)a {
[a addObject:#"B"];
[a addObject:#"C"];
[a addObject:#"D"];
[a addObject:#"E"];
}
#end
ExampleMenuViewController.h
// ExampleMenuViewController.h
// Created by Don Mag on 8/30/20.
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
#interface ExampleMenuViewController : UIViewController
#end
NS_ASSUME_NONNULL_END
ExampleMenuViewController.m
// ExampleMenuViewController.m
// Created by Don Mag on 8/30/20.
#import "ExampleMenuViewController.h"
#import "SomeClass.h"
#interface ExampleMenuViewController ()
{
NSMutableArray *vcTabs;
}
#end
#implementation ExampleMenuViewController
- (void)viewDidLoad {
[super viewDidLoad];
// add a button to the view
//UIButton *b = [UIButton new];
UIButton *b = [UIButton buttonWithType:UIButtonTypeSystem];
[b setTitle:#"Tap Me" forState:UIControlStateNormal];
b.frame = CGRectMake(0, 0, 200, 50);
b.center = self.view.center;
[self.view addSubview:b];
[b addTarget:self action:#selector(btnTapped) forControlEvents:UIControlEventTouchUpInside];
[self initVCTabs];
[self logArray];
}
- (void)initVCTabs {
// instantiate NSMutableArray
vcTabs = [NSMutableArray new];
// add one object
[vcTabs addObject:#"A"];
}
- (void)btnTapped {
SomeClass *sc = [SomeClass new];
[sc moreTabs:vcTabs];
[self logArray];
}
- (void)logArray {
NSLog(#"vcTabs has %ld objects", [vcTabs count]);
for (NSString *s in vcTabs) {
NSLog(#"%#", s);
}
}
#end
When ExampleMenuViewController loads, it will add a button to the center of the view, then instantiate the vcTabs array and add one object - #"A".
We log the array to the debug console and see:
vcTabs has 1 objects
A
When you tap the button, an instance of SomeClass will be created, we call the moreTabs method in that class, passing a reference to vcTabs. That method will add 4 objects to the array - #"B" #"C" #"D" #"E".
We then log the array to the debug console and see:
vcTabs has 5 objects
A
B
C
D
E
#DonMag
It's working but I have one question to you. I added for loop to increment. When I add [additional_tabs count] is return nil. Why this method adds the same objects? My code in addMore function:
- (void)moreTabs:(NSMutableArray *)a {
for (int i = 1; i < additional_tab_count; i++) {
NSString *additionalTabId = [Tools getStringUserDefault:#"conference_additional_tab_id" :#""];
NSString *additionalTabUrl = [Tools getStringUserDefault:#"conference_additional_tab_url" :#""];
[a addObject:[[VCTab alloc] initWithIdAndTypeAndUrl:additionalTabId :VCTabAdditional :additionalTabUrl]];
}
}
Do you know how to get THIS "dictionary" or "additional_tabs". I tried but always return nil (looks like a new other instance and is not this dictionary or additional_tabs from initFromJSON). I only managed to make variable additional_tab_count and it's return 17 (correct count), but I'd rather have access to array from additional_tabs declared in if statements.
I have a Singleton class that has two methods:
- (void)saveString:(NSString *)stringObject {
[[[Singleton sharedInstance] stringArray] addObject:stringObject];
}
- (NSArray *)getArrayContents {
return [[Singelton sharedInstance] stringArray];
}
Here is the implementation code of my Singleton class:
static Singleton *sharedSingleton = nil;
+ (Singleton *) sharedInstance {
if (sharedSingleton == nil) {
sharedSingleton = [[super alloc] init];
}
return sharedSingleton;
}
I have two View Controllers (vcA, and vcB) in my application. What I am trying to do is temporarily store the data from vcA, so that the data inside stringArray will be accessible later to vcB.
Here is the code that vcA uses to store the data:
[[Singleton sharedInstance] saveString:stringName];
Later in the lifecycle of the application, vcB calls the Singleton class to retrieve the values from the NSMutableArray:
NSArray *newArray = [[Singleton sharedInstance] getArrayContents];
for (NSString *test in newArray) {
NSLog(#"Here are the contents of the array %#", test);
}
Unfortunately, when I make the call in vcB to print the contents of the Array, there is no output because the array is empty, despite the fact that values are added to the array. What is it I'm doing wrong?
Try this,
to create Singleton
+(Singleton *)sharedSingleton {
static dispatch_once_t once;
static Singleton *sharedSingleton;
dispatch_once(&once, ^{
sharedSingleton = [[self alloc] init];
});
return sharedSingleton;
}
and the init method of singleton class
- (id)init
{
self = [super init];
if (self) {
//#property stringArray
self.stringArray = [[NSMutableArray alloc] init];
}
return self;
}
Other methods of Singleton
- (void)saveString:(NSString *)stringObject {
[self.stringArray addObject:stringObject];
}
- (NSArray *)getArrayContents {
return self.stringArray;
}
I had this problem. My code in the singleton looked like this:
+ (ReportDataList*)sharedDataArray
{
static dispatch_once_t pred;
static ReportDataList *shared = nil;
dispatch_once(&pred, ^{
shared = [[ReportDataList alloc] init];
self.rDetailsArray = [[NSMutableArray alloc] init];
});
return shared;
}
I had incorrectly initialised the array, so it was emptying it when I created a reference to the singleton later in my code. I removed the array initialisation, which is done in the -(id)init method and it worked fine. So, my code then looked like this:
+ (ReportDataList*)sharedDataArray
{
static dispatch_once_t pred;
static ReportDataList *shared = nil;
dispatch_once(&pred, ^{
shared = [[ReportDataList alloc] init];
});
return shared;
}
- (id)init
{
self = [super init];
if (self) {
self.rDetailsArray = [[NSMutableArray alloc] init];
[self initWithDummyValues];
}else{
NSLog(#"problem initialising array list");
}
return self;
}
First off, these two methods should probably use self, not sharedInstance:
- (void)saveString:(NSString *)stringObject {
[[self stringArray] addObject:stringObject];
}
- (NSArray *)getArrayContents {
return [self stringArray];
}
Second, there’s no point in having a getArrayContents method when you already have stringArray, and get as a prefix is usually reserved for methods that take a parameter to be copied into, anyhow.
Third, I don’t see you initializing stringArray anywhere, so unless there’s code missing, it’s nil and it’s staying nil. Maybe try:
+ (Singleton *) sharedInstance {
if (!sharedSingleton) {
sharedSingleton = [[self alloc] init];
sharedSingleton.stringArray = [NSMutableArray new];
}
return sharedSingleton;
}
Assuming stringArray is declared something like:
#property (readwrite, strong) NSMutableArray *stringArray;
I've been exploring virtual card deck randomisation and drawing of cards as a little side hobby recently, and have been focussing on a great tutorial found at Ontswedder. However, I've run into a minor issue which I'm hoping you can help me with!
Below, I've included some key aspects of the code for your viewing.
In my viewController, I'm wanting to call both the shuffle and draw methods, found in Deck.m. This is possible if I do the following:
Deck *d = [[Deck alloc] init];
[d shuffle];
[d deal];
However, I need to be able to split these. For example, clicking one button initialises the deck, and shuffles it, whilst another new button draws a new card (until the deck is empty).
I am having issues with this, and I could do the following:
Deck *d = [[Deck alloc] init];
[d shuffle];
Deck *d = [[Deck alloc] init];
[d deal];
But this is useless to me, as if I call the init then a NEW, UNSHUFFLED deck is created and the card is dealt from this new deck.
I've tried declaring Deck *DeckObject in viewController.h, then simply calling [DeckObject draw];, however this provides a null value.
Ultimately, I would like to call these two methods separately. Without needing to init a new deck every time if possible!! :-)
I greatly appreciate both everyone's help on this post but also site-wide!
I hope this makes sense, too. Please let me know if you would like more information.
Also, I apologise if any of my terminology is incorrect - still a bit of a newbie!
Included code for context:
Card.h
typedef enum {
Hearts,
Diamonds,
Spades,
Clubs
} Suit;
#define Ace 1
#define Jack 11
#define Queen 12
#define King 13
#interface Card : NSObject {
NSInteger value;
Suit suit;
}
#property (nonatomic) NSInteger value;
#property (nonatomic) Suit suit;
- (id) initWithValue:(NSInteger) aValue suit:(Suit) aSuit;
#end
Card.m
#interface Card(Private)
- (NSString *) valueAsString;
- (NSString *) suitAsString;
#end
#implementation Card
#synthesize value,suit;
- (id) initWithValue:(NSInteger) aValue suit:(Suit) aSuit {
if(self = [super init]) {
self.value = aValue;
self.suit = aSuit;
}
return self;
}
- (NSString *) valueAsString {
switch (self.value) {
case Ace:
return #"Ace";
break;
case Jack:
return #"Jack";
break;
case Queen:
return #"Queen";
break;
case King:
return #"King";
break;
default:
return [NSString stringWithFormat:#"%d",self.value];
break;
}
}
- (NSString *) suitAsString {
switch (self.suit) {
case Hearts:
return #"Hearts";
break;
case Diamonds:
return #"Diamonds";
break;
case Spades:
return #"Spades";
break;
case Clubs:
return #"Clubs";
break;
default:
return nil;
break;
}
}
- (NSString *) description {
return [NSString stringWithFormat:#"%# %#",
[self valueAsString],
[self suitAsString]];
}
#end
Deck.h
#interface Deck : NSObject {
#private
NSMutableArray *cards;
}
- (void) shuffle;
- (Card *) draw;
- (NSInteger) cardsRemaining;
#end
Deck.m
#implementation Deck
- (id) init {
if(self = [super init]) {
cards = [[NSMutableArray alloc] init];
for(int suit = 0; suit <= 3; suit++) {
for(int value = 1; value <= 13; value++) {
Card *card = [[Card alloc] initWithValue:value suit:suit];
[cards addObject:card];
[card release];
}
}
}
return self;
}
int randomSort(id obj1, id obj2, void *context ) {
// returns random number -1 0 1
return (arc4random()%3 - 1);
}
- (void) shuffle {
for(int x = 0; x < 500; x++) {
[cards sortUsingFunction:randomSort context:nil];
}
}
- (Card *) draw {
if([self cardsRemaining] > 0) {
Card *card = [[cards lastObject] retain];
[cards removeLastObject];
return [card autorelease];
}
NSException* myException = [NSException
exceptionWithName:#"OutOfCardsException"
reason:#"Tried to draw a card from a deck with 0 cards." userInfo:nil]; #throw
myException;
}
- (NSInteger) cardsRemaining {
return [cards count];
}
- (NSString *) description {
NSString *desc = [NSString stringWithFormat:#"Deck with %d cards\n",[self
cardsRemaining]];
for(int x = 0; x < [self cardsRemaining]; x++) {
desc = [desc stringByAppendingFormat:#"%#\n",[[cards objectAtIndex:x] description]];
}
return desc;
}
- (void) dealloc {
[cards release];
[super dealloc];
}
#end
When you declare the property deckObject, that just creates the pointer, you still have to alloc init a Deck object to create an instance.
self.deckObject = [[Deck alloc] init];
Then, you can use [self.deckObject shuffle] and [self.deckObject deal]in different button methods.
you have to declaring Deck *DeckObject in viewController.h as below
#interface firstViewController : UIViewController {
Deck *DeckObject;
}
Now in viewController.m file's viewDidLoad method initialize it like below
Deck *DeckObject = [[Deck alloc] init];
after that you can call methods in uibutton's action method
- (IBAction)BtnShuffle:(id)sender
{
if (DeckObject) {
[DeckObject shuffle];
}
}
and
- (IBAction)BtnDraw:(id)sender
{
if (DeckObject) {
[DeckObject draw];
}
}
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
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.