Object in Array is not recognised as having "methods" - iphone

I got my application working Awhile back, but after completely and accidentally deleting it, I have tried to create it from square one. unfortunately my rewritten program is a bit cranky; does anyone see or know the possible sources of error? Also, my if statements are acting up.
-(void)loadAnnotations
{
CLLocationCoordinate2D workingCoordinate;
iProspectLiteAppDelegate *appDelegate = (iProspectLiteAppDelegate *)[[UIApplication sharedApplication] delegate];
NSMutableArray *mines =[[NSMutableArray alloc] initWithArray:(NSMutableArray *) appDelegate.mines];
BOOL gold = [[NSUserDefaults standardUserDefaults] boolForKey:#"goldControl"];
BOOL silver = [[NSUserDefaults standardUserDefaults] boolForKey:#"silverControl"];
BOOL copper = [[NSUserDefaults standardUserDefaults] boolForKey:#"copperControl"];
for(id mine in mines)
{
NSLog(#"in the loop");
workingCoordinate.latitude = [[mine latitudeInitial] doubleValue];
workingCoordinate.longitude = [[mine longitudeInitial] doubleValue];
iProspectLiteAnnotation *tempMine = [[iProspectLiteAnnotation alloc] initWithCoordinate:workingCoordinate];
[tempMine setTite:[mine mineName]];
if ([[mine commodity] isEqualToString:#"Gold"] && [gold == YES])
{
[tempMine setAnnotationType:iProspectLiteAnnotationTypeGold];
[mapView addAnnotation:tempMine];
}
if([[mine commodity] isEqualToString:#"Silver"] && [silver == YES])
{
[tempMine setAnnotationType:iProspectLiteAnnotationTypeSilver];
}
if([[mine commodity] isEqualToString:#"Copper"] && [copper == YES])
{
[tempMine setAnnotationType:iProspectLiteAnnotationTypeCopper];
}
}
[mines dealloc];
}
where the workingCoordinate.latitude = [[mine latitudeInitial] doubleValue], as well as the longitude, and [mine mineName],it says " No '-latitudeInitiallongitudeInitial' method found" or the mineName/LongitudeInitial.
also, it complains about : before ] at all the if statement lines. I don't see any errors, do you?

You are using an iterator that is giving you objects of type id - calling a method on those will often confuse a compiler. Are you able to cast them to a known type?
Like for(MineType* mine in mines)?
And
[tempMine setTite:[mine mineName]];
Is that a typo? My guess is you would be calling that method setTitle.

i think changing the object type of mine object in the for loop to whatever custom class you have with latitudeInitial, longitudeInitial, mineName properties/methods should solve this.

Related

cant able to acess variable from nsarray crash at runtime

I am crashing at runtime when i pop last element from NSMuttable array.I am getting all element fine but when i acess last element it will give error.
-(id)popOperand{
id operandObject = [self.operandStack lastObject];
if(operandObject) [self.operandStack removeLastObject];
return operandObject;
}
For eg:- if in my stack i have "8"(Its NSNumber object) "+"(Its NSString object) 2(Its NSnumber Object).
NSNumber *rightOperand = [self popOperand];
NSString *operation = [self popOperand];
NSNumber *leftOperand = [self popOperand];//when i acess 8 it shows empty array other element is getting fine;
My question is why i am not able to get last object while this function is working fine for other elememts.
EDIT : At run time when after poping 2 it show stack( 8 +) but after i poped + it show stack() empty.But The "leftOperand" is not getting value. I am not using ARC.
Please ellaborate it.
Thanks.
If you aren't using ARC then you have memory management issues:
- (id)popOperand
{
id operandObject = [self.operandStack lastObject]; // Still retained by operandStack
if(operandObject) [self.operandStack removeLastObject];// Released by operandStack
return operandObject; // Could be dealloc'd any time now!
}
Try this version, which returns a retain'd and autorelease'd object, which conforms to the naming convention of the method:
- (id)popOperand
{
id obj = nil;
if ([self.operandStack count] > 0)
{
id obj = [[[self.operandStack lastObject] retain] autorelease];
[self.operandStack removeLastObject];
}
return obj;
}

Works on iOS Simulator but not on iOS device?

EDIT: It works but it takes amazingly long to complete.
Is this normal, or is there a way to optimize it?
Thanks
I am using DDUnitConverter in my project to convert currencies.
Everything works perfectly fine on the iOS Simulator but hangs when I try to convert the currencies on my iOS Device (iPhone 4 iOSv5.1). I looked around to find a fix to this issue but could not find anything. Here is the code that I use to exchange the currencies. The code within the DDUnitConverter is available here: https://github.com/davedelong/DDUnitConverter/downloads
if ([Number.text isEqualToString:#""] || [picklable.text isEqualToString:#"no selection"] || [picklable2.text isEqualToString:#"no selection"]) {
return;
}
if ([Number.text isEqualToString:#"0"]) {
Result.text = #"0";
return;
}
int fromType;
int toType;
fromType = [list indexOfObject:picklable.text];
toType = [list indexOfObject:picklable2.text];
NSNumberFormatter * f = [[NSNumberFormatter alloc] init];
[f setNumberStyle:NSNumberFormatterDecimalStyle];
NSNumber * from = [[f numberFromString:Number.text] retain];
[f release];
NSNumber *to = [[[DDUnitConverter currencyUnitConverter] convertNumber:from fromUnit:fromType toUnit:toType] retain];
float toto = [to floatValue];
Result.text = [NSString stringWithFormat:#"%.4f %#", toto, picklable2.text];
if ((toto == 0 || toto == [Number.text floatValue]) && picklable.text != picklable2.text ) {
Result.text = #"No Internet Connection or Previous Data";
}
[from release];
[to release];
[Result flashScrollIndicators];
Hopefully someone can help me out,
Thanks
Your code seems OK to me, but you are using DDUnitConverter. I've never used it, but I suppose it needs internet connection to load data from the internet. If the server take long time to answer, your app could hang on connection.
You can try to connect to the server asynchronously using dispatch_async, this lets your app download data in background.
Anything taking amazingly long to do should be dispatched. Like this:
dispatch_async(dispatch_get_global_queue(), ^(void) {
[self doReallyAmazinglyComplicatedProcessing];
});

How do I get the index of an object in an NSArray using string value?

I want to get the index of an object within the NSMutableArray of categories.
The category object has an attribute "category_title" and I want to be able to get the index by passing the value of category_title.
I have looked through the docs and can't find a simple way to go about this.
NSArray does not guarantee that you can only store one copy of a given object, so you have to make sure that you handle that yourself (or use NSOrderedSet).
That said, there are a couple approaches here. If your category objects implement isEqual: to match category_title, then you can just use -indexOfObject:.
If you can't do that (because the category objects use a different definition of equality), use -indexOfObjectPassingTest:. It takes a block in which you can do whatever test you want to define your "test" - in this case, testing category_title string equality.
Note that these are all declared for NSArray, so you won't see them if you are only looking at the NSMutableArray header/documentation.
EDIT: Code sample. This assumes objects of class CASCategory with an NSString property categoryTitle (I can't bring myself to put underscores in an ivar name :-):
CASCategory *cat1 = [[CASCategory alloc] init];
[cat1 setCategoryTitle:#"foo"];
CASCategory *cat2 = [[CASCategory alloc] init];
[cat2 setCategoryTitle:#"bar"];
CASCategory *cat3 = [[CASCategory alloc] init];
[cat3 setCategoryTitle:#"baz"];
NSMutableArray *array = [NSMutableArray arrayWithObjects:cat1, cat2, cat3, nil];
[cat1 release];
[cat2 release];
[cat3 release];
NSUInteger barIndex = [array indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
if ([[(CASCategory *)obj categoryTitle] isEqualToString:#"bar"]) {
*stop = YES;
return YES;
}
return NO;
}];
if (barIndex != NSNotFound) {
NSLog(#"The title of category at index %lu is %#", barIndex, [[array objectAtIndex:barIndex] categoryTitle]);
}
else {
NSLog(#"Not found");
}
Not sure that I understand the question but something like this might work (assuming the Mutable Array contains objects of Class "Category"):
int indx;
bool chk;
for (Category *aCategory in theArray)
{
chk = ([[aCategory category_title] isEqualToString:#"valOfCategoryTitle"])
if ( chk )
indx = [theArray indexOfObject:aCategory];
}
Try this code much more simpler:-
int f = [yourArray indexOfObject:#"yourString"];

Game Center multiplayer code

As per the docs, I'm using:
- (void) match:(GKMatch*) match
player:(NSString*) playerID
didChangeState:(GKPlayerConnectionState) state;
to carry out the initial game negotiation. I do this in the scope of:
if (matchStarted_ == NO && [match expectedPlayerCount] == 0) { ... }
I need to decide which device is responsible for setting up the game. I do this by sorting the match.playerIDs NSArray instance and comparing the [GKLocalPlayer localPlayer].playerID NSString to the playerID NSString at index 0 of the sorted array. This player creates the game, sending out the data to all players.
However, and even with an expectedPlayerCount of 0, the playerIDs array has zero entries at this point, giving me an array overrun. Why is that? And what should I do instead to make a well-defined choice of player to generate the game?
For the decision code, take a look at the GKTank example provided by Apple - they take a hash of the device id, send it to the other client, and whichever has the lower number is the "host". That seems like a pretty solid way to decide.
here is sample code to do that thing
NSString *uid = [[UIDevice currentDevice] uniqueIdentifier];
CoinTossID = [uid hash];
now in delegate Function
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID
{
NSMutableArray *ReceivedArray = [[NSMutableArray alloc] init];
ReceivedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
int flag = [[ReceivedArray objectAtIndex:0] intValue];
[ReceivedArray removeObjectAtIndex:0];
int CoinValue = [ReceivedCoinTossID intValue];
if(CoinValue > CoinTossID)
{
isPlayer1 = YES;
}
else
{
isPlayer1 = NO;
}
}

What is causing memory leaks?

What is causing the leaks in this code? I really cannot understand it.
On thes lines:
1: NSMutableArray * days = [[NSMutableArray alloc]init];
2: [dic setObject:days forKey:key];
3: [days addObject:value];
The whole method:
-(void) addValueToDictionary: (NSMutableDictionary *) dic withValue: (NSNumber *) value forKey: (NSString *) key {
NSMutableArray * days = [dic objectForKey:key];
if (days == nil) {
NSMutableArray * days = [[NSMutableArray alloc]init];
[days addObject:value];
[dic setObject:days forKey:key];
[days release];
days = nil;
}
else {
[days addObject:value];
}
}
BR
//Christoffer
Check to make sure that dic is released. You should NSLog retainCount before where you think the final releases are and make sure they are 1 right before the final release.
Also, run a Build and Analyze to make sure you are releasing correctly. The built in Build and Analyze doesn't find as many leaks as running scan-build with all checks, so look into installing scan-build into Xcode as well.
Using an external Xcode Clang Static Analyzer binary, with additional checks
You should be getting a warning about re-declaring days. This may be throwing the leak check off if you are using the static analyser. Modified method below. Mostly coding style changes with a little defensive coding added.
-(void) addValueToDictionary: (NSMutableDictionary *) dic withValue: (NSNumber *) value forKey: (NSString *) key
{
if (nil == dic || nil == key || nil == value) return; // bail out on nil parameters
if (![dic objectForKey:key]) {
NSMutableArray * days = [[NSMutableArray alloc] init];
[dic setObject:days forKey:key];
[days release];
}
[[dic objectForKey:key] addObject:value];
}
Have you tried to change the name of the variable NSMutableArray *days within the if? Don't you get a warning because of that?
There's nothing wrong with that particular piece of code (other than the slightly questionable redefinition of days in the inner scope). Somewhere else you are retaining but forgetting to release the object you put in the dictionary.
change NSMutableArray initialization to...
NSMutableArray * days = [NSMutableArray array];