I am making a book application. To move to the next topic I am using a button. The Button works as it moves to the next topic, but at the end of the file my application gets the message obj_fatal and it crashes. If I knew how many objects there are in my NSArray then the problem will be solved. I am getting the details from a .plist file and storing it in to a array.
So if any one knows how, please let me know.
Thanks in advance.
Viral.
-[NSArray count]
Alternatively, if you prefer the look and feel of a property, you can do the following, assuming your NSArray is called myArray:
myArray.count
which is the same as #shosti's method, but looks different.
The difference is readability. So you could have:
if ([myArray count] > 0)
or you could have
if (myArray.count > 0)
which probably looks neater.
Both answers are good and correct. Whichever you choose depends on your coding style. As I said, both ways accomplish the same thing and call the same getter method.
Hope that helps.
Related
I see item UISearchBar search two arrays and very much items and not found solution, the problem its similar, have two NSMutablesArrays "subdetail" and "sublista" its show in Cell cell.textLabel and cell.detailTextLabel.
I try UISearchbar but i tray with NSPredicate and not run, try with NSRange and have more errors, i am desperate.PLEASE help me, any comments agree.
This its my code in Search:
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
NSMutableDictionary *playas = [NSMutableDictionary dictionaryWithObjectsAndKeys:sublista, #"nombre", subdetail, #"localidad", nil];
[alldata addObject:playas];
for(NSDictionary *playas in alldata){
NSString *nombre = [playas objectForKey:#"nombre"];
NSRange nombreRange = [[nombre lowercaseString] rangeOfString:[searchText lowercaseString]];
if(nombreRange.location != NSNotFound)
[filteredList addObject:playas];
}
}
Add rest of code .m and .h
https://dl.dropboxusercontent.com/u/6217319/BuscarViewController.h
https://dl.dropboxusercontent.com/u/6217319/BuscarViewController.m
Thanks in advance.
BEST REGARDS
Your code has a lot of issues with it. I don't know which ones are actually breaking it, but any of these issues could be causing severe problems.
First, the code sample you provided doesn't provide declarations for a lot of hte objects you're referencing. No way this could possibly compile as given. If these are properties of the view controller instance, you need to use the accessor methods -- self.alldata or [self alldata], whichever you prefer.
Second, it looks like you're just adding to these properties. If you never reset their contents, every time this method is called, you're going to increase the size of your data set -- looking at your code, possibly recursively.
Third, you try to merge the two datasets together, and then try to search through only one of them. Either don't merge, or search through both seperately and then merge the results. As it is, what you're doing won't work.
Fourth, your table view should really only be displaying one type of data, so you shouldn't need to merge.
Edit:
Based on the code samples you've provided, your entire VC is going to need restructuring. Given how much of your code is written in what appears to be spanish, I'm doing a bit of guesswork at what you're actually doing.
First off, assuming you're using a modern version of xcode, get rid of the #synthesize in the .m file (it's no longer needed anymore). That will cause every single place you're using the actual ivar instead of a proper getter to turn into an error, so you can fix them quickly. iVars will by default use a prefixed underscore of their property name, so you can still access them if you have to -- but only by explicitly accessing the ivar instead of the property.
Second, you should restructure how you handle the data. I don't know where you get your data, but it looks like the various objects are fairly consistent. You should go ahead and either create a new class to hold all the data, or just put them all into a single dictionary. At that point, the 'alldata' property should, in fact, be an array of all valid data. What you should do is then have a filtered list of data (filteredData would be a good name), and you place whatever data matches the search criteria in there. Just remember to either reload the table or update it appropriately as items move into and out of the filtered list.
In a certain view I have a bunch of AVAudioPlayer properties, each one is supposed to be played upon a certain user action. While the selected AVAudioPlayer is played, if another AVAudioPlayer was played - it should stop.
To manage that, I've created an Array that holds all the AVAudioPlayer properties and upon user selection, before playing the selected AVAudioPlayer, I wish to go over all the AVAudioPlayers and stop them.
The problem is that the reasonable place to create the Array is at the beginning (let's say, in ViewDidLoad) and at this point none of the AVAudioPlayer properties went through alloc+init - so if I look at the Array in the debugger it shows as empty (number of objects = 0). Currently, I do the alloc+init action only when the user is actually selecting a certain AVAudioPlayer.
I can do alloc+init for all the AVAudioPlayers at the beginning as well, but that will take resources that are not necessarily required.
Is there a way to create this Array without taking the required resources? i.e. create the array with "empty" objects and later have them be allocated and initiated?
I have a similar situation. What I've been doing is:
NSArray *myArray = [NSArray arrayWithObjects:#"",#"",#"",#""];
in viewDidLoad (if my array is going to have 4 objects). Then as I have the information available, I do:
[myArray replaceObjectAtIndex:myLocationToAddValue withObject:myObject];
I got the idea for this looking at some code in a very old project written in a completely different language by someone else from my company. It seems to be working for what I need, and it does have the added benefit that I can loop through my array and check
if ([[myArray objectAtIndex:i] length] == 0)
to see where I have items already. I should note that the objects I'm adding are going to all be NSStrings - if this loops through and finds an object has been put into the array that isn't a string (or, more generally, doesn't have a "length" method), I'm guessing some nasty stuff would happen, but I haven't checked for that yet.
I'm certain there must be a much better solution, but I'll put it out there since there haven't been any answers to this yet. I figure a sloppy answer that seems to be working is better than no answer.
Is there a way to tell if a certain object is in an NSArray? The way I am adding objects to my array makes it possible for the same object to be added multiple times and I wanted to see if there was a way to see if it was already there (anywhere) in that array.
The NSArray containsObject: method is precisely for this purpose, its full signature being:
- (BOOL)containsObject:(id)anObject
See the full NSArray Class Reference docs for more information.
if([yourArray indexOfObject:yourObject] == NSNotFound) {
// your object is not in here
}
Edit: middaparkas approach is way better (if you don't want the index …)!
In my game I want to save a set of integers as statistics players can view. E.g number of deaths. This is an int I simply increase by one each time they get a game over.
How can I save this then have it at that number when I relaunch the game?
Thanks.
EDIT:
Ok after reading a few answers Im thinking writing to a plist is the way forward. I have been looking at tutorials but lets say I try this:
scoreData *score = [scoreData sharedData];
[dictionary setValue:score.highScore forKey:#"key2"];
[dictionary writeToFile:#"stats.plist" atomically:NO];
I have accessed my singleton with my score inside. Now when trying to setValue I get an error saying Im trying to convert an int to object.
Im not sure how else to approach it. It seems simple enough, however everywhere I look seem to give essentially the same approach.
Thanks for the help thus far, anymore is appreciated.
I would not abuse NSUserDefaults (Apple discouraged this at WWDC this year). Instead why not simply create an NSMutableDictionary and then store NSNumber objects in it. The MutableDictionary can easily be written to file and as is easily read in.
Any number of a lot of ways.
If you are only saving this and maybe a couple other simple things, using user defaults is probably the best idea.
If however, you are saving a lot more items than just a few, you may want to either use your own property list (if the number of items is less than 200 or so).
If you have a lot of settings, I generally advise folks to look at Core Data instead. It's fast with lots of items, whereas the other two, not so much.
Try...
[[NSUserDefaults standardUserDefaults] setInteger:highScore forKey:#"HighScore"];
highScore = [[NSUserDefaults standardUserDefaults] integerForKey:#"HighScore"];
You can write to a file (i.e. plain C functions fopen() etc), can use your own classes and use NS(Keyed)Archiver, or use NSUserDefaults to save data.
I'm working on an existing, large-ish codebase, and after upgrading the iOS SDK to 4.1 I am now seeing very strange behaviour. The crux of the matter appears to be a particular class that will no longer alloc - it is throwing a bad access in obj_msgSend, and seems to be the Class object on the stack that objc_msgSend doesn't like - although it is not actually NULL.
The original failing line looked like this:-
tileProjection = [[RMFractalTileProjection alloc] initFromProjection:proj tileSideLength:sideLength maxZoom:18];
I deconstructed this to isolate the problem:-
RMFractalTileProjection *p = [RMFractalTileProjection alloc]; // <- this crashes
p = [p initFromProjection:proj tileSideLength:sideLength maxZoom:18];
tileProjection = p;
I then tried this:-
Class c = NSClassFromString(#"RMFractalTileProjection");
assert(c);
NSLog( #"RMFractalTileProjection class(ptr) %p", c ); // <- prints an address OK
NSLog( #"RMFractalTileProjection class(obj) %#", c ); // <- crashes
In the debugger it looks like the Class object is sensible, but NSLog crashes when it tries to print it.
One thing to note: the class in question is declared as below, and I'm not sure if the protocol is causing a problem. Because this particular part is a large chunk of open source code, it is very difficult to remove this protocol requirement to see if that makes a difference.
#interface RMFractalTileProjection : NSObject<RMMercatorToTileProjection>
{
...
}
Any help on this one greatly appreciated - it is a show stopper.
Thanks
This is not really an answer but some ideas to move forward.
The only causes that leap to mind at the moment are memory corruption and some sort of link issue. Perhaps you are linking two versions of the class somehow.
Assuming this is the class, there doesn't look to be anything wrong to make it crash in alloc. There's no +initialize or anything.
Questions I would be asking myself and trying to answer are:
what happens if I rename the class?
what happens if I create a new identical class with a different name?
the pointer that gets passed to obj_msgSend: is it reasonable? does it point to something that looks like a class?
do you ever subclass the class and do you use initialize on the subclass?
is the pointer always the same? If so you can watch what it points to and see if it changes during execution.
what happens if you send self to the class?
OK, finally found this. As Jeremy suggested, this turned out to be a regular memory stomper.
The difficulty I had finding it was that it wasn't the Class object itself that was getting stomped, but the class' metaclass structure - which is a normal Class object but one level up, referenced by the class 'isa' pointer. That's why the class looked OK to me when I inspected it in the debugger - I need to follow the isa pointer and dump memory at one level up to find this. Luckily for me, the class was only a subclass of NSObject - had it been deeply subclassed, this could have been much harder to find. I got my first clue after biting the bullet, reverse-engineering objc_msgSend, working out exactly what was on the stack frame, and following all the pointers. Yep, the hard way :)
Matt Gallaghar's post (and various others I found by following links) were invaluable in helping me through this maze - thanks guys!
Burned a lot of time on this one, but on the up side I learned a hell of a lot about Objective C internals during the past day and a half :)
Thanks for these suggestions JeremyP - it is always good to have fresh suggestions after you've been banging your head against the keyboard all day!
Your suggestion of creating an identical class with the same name appears to have fixed the problem. I have no idea why and I feel I need to understand what's going on here. You're right it sounds like some kind of linker issue, but I still have no idea what could cause such a serious runtime error and not even produce a warning at build time.
Re. the pointer, it does look reasonable, but something inside the class eventually gets dereferenced as a null pointer inside objc_msgSend. Occasionally, after I have changed the code and rebuilt, I get a null pointer instead. This behaviour obviously suggests something nondeterministic like a memory stomp.
I'll post my findings.