I'm creating a little game using Sprite-kit and i'm having problems trying to store an object which means an enemy in the game.I use the same strategy that i use in my C++ programs but with objective-C and pointers the strategy doesn't work.
enemigo *nemesis = [[enemigo alloc] init];
self.almacenEnemigos = [[NSMutableArray alloc] initWithCapacity:kNumEnemigos];
for(int i = 0; i < kNumEnemigos; i++)
{
[nemesis pintarEnemigo:CGPointMake(20+5*i, 20+5*i)];
[self.almacenEnemigos addObject:nemesis];
}
I want to create four enemies but at the end i only have four times the same memory address according to a unique enemy. The var almacenEnemigos is an class attribute in the SKScene class.
You're only creating one instance of enemigo, there in your first line. You need to move the creation of the instances into the loop.
self.almacenEnemigos = [[NSMutableArray alloc] initWithCapacity:kNumEnemigos];
for(int i = 0; i < kNumEnemigos; i++)
{
enemigo *nemesis = [[enemigo alloc] init];
[nemesis pintarEnemigo:CGPointMake(20+5*i, 20+5*i)];
[self.almacenEnemigos addObject:nemesis];
}
Related
I am new to Objective-C and maybe this question is quite stupid but I'm a little confused about it.
Suppose, I have a class and that class contains two different NSMutableArrays: library and playlists. Playlists is an instance variable while library is a property (they are for different purposes). Now, to work with library I have to alloc init it (for example, in an initialiser method). But why shouldn't I do the same for playlists?
When I try to do the same for playlists, my code stops working, but when I don't do it, it works fine (I can add objects to playlist, for example).
EDIT
The example when this happens is in the code snippets below. I have two classes Playlist and MusicCollection. MusicCollection has two arrays: library (property), which contains all songs from all playlists, added to the second array called playlists (instance variable). The code that doesn't work is this one:
-(void)addPlaylist:(Playlist *)thePlaylist {
if ([playlists indexOfObjectIdenticalTo:thePlaylist] != NSNotFound) {
NSLog(#"ADDED");
[playlists addObject:thePlaylist];
[library addObjectsFromArray:thePlaylist.mySongs];
}
}
When I have this initialisation method the code above works fine:
-(instancetype)initMusicCollectionWithName:(NSString *)nameOfPlaylist {
self = [super init];
if (self) {
self.name = nameOfPlaylist;
library = [[NSMutableArray alloc] init];
}
return self;
}
But when I have something like this, it doesn't (it just doesn't add playlists to the playlists array).
-(instancetype)initMusicCollectionWithName:(NSString *)nameOfPlaylist {
self = [super init];
if (self) {
self.name = nameOfPlaylist;
library = [[NSMutableArray alloc] init];
playlists = [[NSMutableArray alloc] init];
}
return self;
}
EDIT 2
As asked, here are the declarations for two arrays:
(library array)
#interface MusicCollection : NSObject
#property(nonatomic, copy) NSMutableArray *library;
(playlists array)
#implementation MusicCollection{
NSMutableArray *playlists;
NSRange range;
}
Could you explain why this happens, please?
Because
self.name = nameOfPlaylist;
gives a strong non-nil reference to name string as you declared it as nonatomic , copy from nameOfPlaylist parameter
so library will work if you pass it like name
-(instancetype)initMusicCollectionWithName:(NSString *)nameOfPlaylist library:(NSString*)lib{
self = [super init];
if (self) {
self.name = nameOfPlaylist;
library = lib;
}
return self;
}
wether it's instance variable or property it must be allocated
and when allocated
Im trying to inset data in to the array (temp) but for some reason it saves the same data over an over. I all ready checked the _singleSeismicInfo to verify that it was handling different data(you can see it in the double "/" printData method). So i know the problem is with the MutableArray.
Im new to iOS so if theres something Im not doing right let me know.
NSMutableArray *temp = [[NSMutableArray alloc] init];
[_httpContent getTextFromHTTP];
for (int index = 0; index < 10; index++) {
NSString *line = _httpContent.lines[index];
[_singleSeismicInfo fillSeismicInfo:line];
//[_singleSeismicInfo printData];
[temp addObject:_singleSeismicInfo];
}
You're adding _singleSeismicInfo over and over without ever reassigning a new object to the variable as far as I can see. So it's the same object over and over because that's what you add.
This question already has answers here:
how to instantiate an object of class from string in Objective-C?
(2 answers)
Closed 9 years ago.
All is in my title, i want to create some dynamics names, to allocate some differents UIViews but randomly. For example, i want to make :
Level1 * level1view = [[Level1 alloc] init];
So i try to make some NSString like this :
ClasseMap = [NSString stringWithFormat:#"Level%i", Map];
NomMap = [NSString stringWithFormat:#"level%iview", NumeroMap];
id nouveau = NSClassFromString(ClasseMap);
nouveau * ViewTest;
ViewTest = [self valueForKey:NomMap];
ViewTest = [[nouveau alloc] init];
But it gives me : Use of undeclared identifier 'ViewTest'. How could i fix it please ? How could i get access to some variables (for example, level1view.example = YES;) ?
Thanks for your help ! =)
why dont you rather keep an array of views instead?
int Map = 0;
int NumeroMap = 1;
NSMutableArray *array = [[NSMutableArray alloc] init];
//add your views (levels?) to the array
[array addObject:someUIView];
[array addObject:someOtherUIView];
//now you can use your indexes to access the views you want
UIView *yourView = [array objectAtIndex:Map];
UIView *anotherView = [array objectAtIndex:NumeroMap];
i think what you are trying to do is not the way to go about things.
I have this function in which the function insertObject:AtIndex:0 behaves weird . After inserting all objects to the NSMutableArray cardViewControllers, the final element is always nil.I did alloc init the cardViewControllers at the beginning in the init method.
- (void)reloadCardViews;
{
// Add the restaurants onto view
[self removeAllCards];
for (int i = 0; i < NO_OF_CARDS; i++) {
SHCCardVC *vc = [[SHCCardVC alloc] initWithAppearanceIndex:i];
vc.delegate = self;
[cardViewControllers insertObject:vc atIndex:0];//it's behaving weird here
[self addChildViewController:vc];
// set card position to center of the container
vc.view.center = CGPointMake(_cardContainer.frame.size.width / 2, _cardContainer.frame.size.height / 2);
[_cardContainer addSubview:vc.view];
}
_currentCardViewIndex = 0;
_currentCardIndex = 0;
}
What does [self removeAllCards] do? I suspect that you call [cardViewControllers removeAllObjects]? Have you tried using [cardViewControllers addObject:vc]? If this works and the order is important, walk trough your for loop from behind with i--.
Also make sure your objects are not nil and your array is mutable and also initialized. I had a similar problem with an uninitialized mutable array.
You can't add nil objects to arrays, it's a runtime error. So something must be going weird with the retain count, that's all I can think at the moment. NSArray retains objects that are within it, so the object is being released one too many times somewhere.
Is this a possibility?
I have a mutablearray that is populated from sqlite db in ios. I have gotten the annotations to load and view properly. My question is how can I write a loop that will add annotations with the size of the array. I have tried the following code and get and display the last entry in the array
NSMutableArray *annotations=[[NSMutableArray alloc] init];
CLLocationCoordinate2D theCoordinate5;
MyAnnotation* myAnnotation5=[[MyAnnotation alloc] init];
for (int i = 0; i < _getDBInfo.count; i++) {
dbInfo *entity = [_getDBInfo objectAtIndex:i];
NSNumber *numlat=[[NSNumber alloc] initWithDouble:[entity.Latitude doubleValue]];
NSNumber *numlon=[[NSNumber alloc] initWithDouble:[entity.Longitude doubleValue]];
NSLog(#"%d",[_getDBInfo count]);
la=[numlat doubleValue];
lo=[numlon doubleValue];
theCoordinate5.latitude=la;
theCoordinate5.longitude=lo;
myAnnotation5.coordinate=theCoordinate5;
myAnnotation5.title=[NSString stringWithFormat:#"%#"entity.EntityNo];
myAnnotation5.subtitle=[NSString stringWithFormat:#"%#",entity.EntityName];
[mapView addAnnotation:myAnnotation5];
[annotations addObject:myAnnotation5];
}
I guess my question is how can I create and add to my view annotation objects based on the count in my array?
Any help is much appreciated.
I am new to iOS as well as programming so please be gentle.
You only have one myAnnotation5 object. When you set its coordinate, title, etc., you are setting it for that instance, which you happen to have added to annotations multiple times. Hence every entry in annotations will have the last set of properties you set - since every entry in annotations is actually the same object.
To remedy this, you need to create your myAnnotation5 object anew each iteration of the loop, i.e.
for (int i = 0; i < _getDBInfo.count; i++) {
MyAnnotation* myAnnotation5=[[MyAnnotation alloc] init];
...
myAnnotation5.coordinate=theCoordinate5;
myAnnotation5.title=[NSString stringWithFormat:#"%#", entity.EntityNo];
myAnnotation5.subtitle=[NSString stringWithFormat:#"%#", entity.EntityName];
...
[mapView addAnnotation:myAnnotation5];
}
Two asides:
I hope you are building with ARC, otherwise you are leaking memory left and right.
Since MKMapView has an -annotations property, there is likely little reason for you to keep your own annotations array - just keep a reference to mapView.
Move this line:
MyAnnotation* myAnnotation5=[[MyAnnotation alloc] init];
to inside the for-loop just before setting the properties on myAnnotation5.
The way it is right now, you are creating only one MyAnnotation object and modifying its properties repeatedly.