From an array, I want to make a new mutable array holding all the items that meet a certain criteria. That's not the problem. The problem is checking if the array is empty.
if (!theDates]) {/*do something*/}
it comes back positive regardless, because the mutable array was created. But
if (![theDates objectAtIndex:0])
{
/* nothing got added to the array, so account for that */
}
else
{
/* do something with the array */
}
It crashes.
This crashes because although you have allocated your array, it's still empty. The line [theDates objectAtIndex:0] is trying to access the first object of an array, and due your array has none yet, it will crash.
To check the integrity of your array, just do this:
if (theDates.count > 0)
{
//Do something
id object = theDates[0]; //this for sure won't crash
}
Use [theDates count] > 0. You're accessing a possibly non-existent element, so it will crash when it's empty.
Or you could use the lastObject method which will return nil if the array is empty
if (![theDates lastObject]) { do something }
if( (theDates!=nil) && (theDates.count > 0))
{
//We have and existing array and something in there..
}
if (theDates != nil){
if (theDates.count > 0){
'do something'
}
}
This should check null array then check empty array which prevents nullpointerexception arises
This will work fine..
if (!URarray || !URarray.count){
// write code here
}
Related
I'd like to check for an empty object (i.e. an object of an array which doesn't have a value) within an array which gets its data from a file.
As an example, if my array contains 12 objects (all NSString) and the object at index 11 doesn't return a value when its description is printed into the debug section of Xcode. I want to check if that is the case and respond accordingly. I already tried
if (!([MY_ARRAY objectAtIndex:11] == nil))
{
//Some Stuff
}
else
{
//Some other Stuff
}
which didn't work.
Any help is appreciated.
The description method is for debugging. You should not use it in your program logic. What are these objects, and what do they contain? Can you modify the objects to add an "isEmpty" property?
If you use NSNull, you'd use code like this:
NSArray *array = #{#"String", #(4), [NSNull null], #"Another string");
for (id anObject in array)
{
if (anObject =! [NSNull null]))
{
//Some Stuff
}
else
{
//Some other Stuff
}
}
You can check the length of the string: [string length] > 0
an object is an array cannot be nil, but you can use [NSNull null] which is an "object equivalent" to nil
As Jerome Diaz states, objects in an array can't be nil. The only option you have is to check the count property of the array if it reflects an expected value, or you can inspect the type/class of the object in the array. A safe way to include empty object into array is [NSNull null], but this is the task for the method that fills the array, not the one that reads it.
You can check the class type of an object in array with isKindOfClass or isMemberOfClass.
I have a NSDictionary (MyDictionary) which is currently returning "0 objects" for the
[mylist] key:value pair.
MyDictionary:
{
mylist = (
);
}
How can I check if the value for the key contains 0 objects?
I've tried the following without success:
if([MyDictionary objectForKey:#"mylist"] !=[NSNull null]){} //evaluates to false
if([MyDictionary valueForKey:#"mylist"] !=[NSNull null]){} //evaluates to false
NSNull is not the same thing as nil.
NSArray *myList = MyDictionary[#"mylist"];
if (myList.count == 0) {
//empty or nil!
}
Your dictionary has one key-value pair, where the value is an empty NSArray. Note that an empty NSArray is not the same as an NSNull object, nor is it even a nil pointer. It is in fact, a valid pointer to an NSArray object that just happens to have nothing in it.
To determine that there are no elements in the array, you must first extract the array from the dictionary, and then check the count of the array to determine whether it has any elements. This can all be done in one line of code like this
if ( [MyDictionary[#"mylist"] count] == 0 )
// array is empty
The value is an array. To check if an NSArray is empty, you can check whether its length is 0.
arrdata=[[NSMutableArray alloc]initWithObjects:strname,strWeb,strAdd,strPhone,strrate, nil];
[arrAllData addObject:arrdata];
I fetched data from a webservice. in my condition if strweb has no value then it simply ignores other values like stradd,sphone and strrate. How can I solve this problem?
you can do like this in a simplest way.
if(strweb==nil)
{
strweb=#"null";
}
Note: pass null in <> bracket;
Try this code,
if(strWeb == nil){
strWeb = [NSString stringWithFormat:#"%#", [NSNull null]];
}
arrdata=[[NSMutableArray alloc]initWithObjects:strname,strWeb,strAdd,strPhone,strrate, nil];
[arrAllData addObject:arrdata];
When your any object nil while creation time of array then your array will be end with than object and remaining objects will discards. That why you need to check every object should not be nil according above code stuff then add it into array.
If strWeb is nil then your array structure will be
arrdata=[[NSMutableArray alloc]initWithObjects:strname,nil]; future object will discard.,strAdd,strPhone,strrate,
output of arrdata containg only one object strname
Other way,
Set any default value if your string is nil. for example,
if(strWeb == nil){
strWeb = #"This Value is discarded"; // It could be anything identifier for your purpose.
}
arrdata=[[NSMutableArray alloc]initWithObjects:strname,strWeb,strAdd,strPhone,strrate, nil];
[arrAllData addObject:arrdata];
While retrieving time you can match above string with value inside the object.
You use the initializer -initWithObjects:. As you know the object list is terminated with nil. If one of the references has the value nil, -initWithObjects: thinks that this is the terminator.
Check the references (i. e. strweb). If it is nil, assign a default value to it or do not encounter the variable in the list.
I knows some ways to avoid this, for example
if (index >= [_data count] || index < 0) return nil;
return [_data objectAtIndex:index];
But should i aways do this? or are there any other solutions about this topic?
First, I'd like to echo #rmaddy's comment, which is spot on:
There is no general solution. Every case is different.
That said, there are other techniques you can use:
firstObject and lastObject
These methods will return the object, or nil if there is none. These methods will never throw an exception.
Fast Enumeration
You can use fast enumeration and never need to check the indices:
NSArray *myStrings = #[#"one", #"two"];
for (NSString *thisString in myStrings) {
NSLog(#"A string: %#", thisString);
}
Safe Category
You can add a category on NSArray if you find yourself doing this frequently:
- (id)safeObjectAtIndex:(NSUInteger)index {
if (index >= [self count] || index < 0) return nil;
return [self objectAtIndex:index];
}
See Customizing Existing Classes if you aren't familiar with categories.
One downside of this is it may be harder to find errors in your code.
In apple library NSArray objectAtIndex method:
objectAtIndex:
Returns the object located at the specified index.
- (id)objectAtIndex:(NSUInteger)index
Parameters
index
An index within the bounds of the array.
Return Value
The object located at index.
You can use "NSUInteger index ;" so "if (index < 0)" could be omitted.
In my opinion, if you need to provide some interface to others, you may need to add these code to avoid "beyond bounds".
But if your code just works for yourself, you need not to do the stuff because most of time what you needs is an object in the array but not the nil. If the index beyonds bound, there must be some logic error which you need to fix. Let exception goes and find your bug.
U can swizzle the objectAtIndexmethod,before call objectAtIndex, invoke method like 'custom_objectAtIndex' to check if out of bounds .
+ (void)load{
Method method1 = class_getInstanceMethod(objc_getClass("__NSArrayI"),#selector(objectAtIndex:));
Method method2 = class_getInstanceMethod(objc_getClass("__NSArrayI"),#selector(custom_objectAtIndex:));
method_exchangeImplementations(method1, method2);
}
- (id)custom_objectAtIndex:(NSUInteger)index{
NSLog(#"~~~~~~~:%ld",count);
if (index >= self.count) {
return #"out of bounds";
} else {
return [self custom_objectAtIndex:index];
}
}
I need to check if a certain array contains a certain object, and if it does, delete that object. If it hasn't got that object, the funciton is suposed to add it into the array. The problem is that the object is always added because the checking statement always return false.
Here's my current function:
- (void) myFunction:(NSString *)parameter {
if (![myMutableArray containsObject:parameter]) {
[myMutableArray addObject:parameter];
NSLog(#"%# added", parameter);
} else {
[myMutableArray removeObject:parameter];
NSLog(#"%# deleted", parameter);
}
}
containsObject is calling isEqual on each of the object in the arrays. What type of object are you checking for? If it's a custom object, override and implement the method isEqual.
I'm guessing you're trying to check the value of the object, but containsObject is actually calling isEqual which is comparing the reference to the object, and not its actual value.
if (![arrList containsObject:arrObj]) {
// do something
}
containsObject:
First you need to check which type data or object you are adding in this myMutableArray. According to your method you are checking in mutable array for string type that you have passed argument parameter. It may be possible that you are containing int or float array.
There may be issue of type casting in your array.If your is STRING type of data then you can use another method like this.
- (void) myFunction:(NSString *)parameter {
for (int i = 0 ; i < [myMutableArray count ] ; i++) {
if (![[myMutableArray objectAtIndex:i] isEqualToString:parameter]) {
[myMutableArray addObject:parameter];
NSLog(#"%# added", parameter);
}
else{
[myMutableArray removeObject:parameter];
NSLog(#"%# deleted", parameter);
}
}
}
Hope this will help you. If your object is not type of NSString then you need to convert.
You should implement isEqual: in your custom class. By default two objects are only identical if they share the same reference.
Also make sure to initialize your mutable array before using it.
EDIT:
It seems that your array's variable name are most probably mistyped.
myMutableArray
myMutbaleArray
You probably forgot to initialize your NSMutableArray. If not initialized, you are sending addObject messages to a nil object, which has no effect, and the array never contains what you previously added...
Of course, if the array is nil, then the contains check will always return false. According to the Objective-C docs:
If the method returns an object, any pointer type, any integer scalar
of size less than or equal to sizeof(void*), a float, a double, a long
double, or a long long, then a message sent to nil returns 0.
And 0 is false