NSMutableArray EXEC_BAD_ACCESS on initWithObjects - objective-c

Is the following legal in Objective-c with ARC enabled?
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
I thought it should be. However, in this situation it gives me EXEC_BAD_ACCESS on the forth line:
NSMutableArray * bigArray = [[NSMutableArray alloc] init];
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
[bigArray addObject: smallArray];
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
addObject copies the pointer right? So if I allocate a new segment of memory to smallArray to point to, what is wrong with that?
However this code segment does not crash:
NSMutableArray * bigArray = [[NSMutableArray alloc] init];
NSMutableArray * smallArray = [[NSMutableArray alloc] initWithObjects:#"1", #"2", #"3", nil];
[bigArray addObject: smallArray];
smallArray = [[NSMutableArray alloc] init];
[smallArray addObject:#"4"];
[smallArray addObject:#"5"];
What's going on here?

Try this:
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", "5", nil];
The second object must be #"5", not just "5".

I guess this is because you forgot the # in the string "5". it should be:
smallArray = [[NSMutableArray alloc] initWithObjects:#"4", #"5", nil];

Related

Converting NSMutableSet to NSSet

Is there a way to convert NSMutableSet to NSSet? I have tried several methods: moving to an NSArray and the setWithArray; instantiating an NSSet with the contents of the NSMutableSet. The program compiles but I get a run time error.
NSMutableArray *temp = [[NSMutableArray alloc] init];
NSMutableSet *num1 = [[NSMutableSet alloc] init];
NSArray *num2 = [[NSArray alloc] init];
NSSet *num3 = [[NSSet alloc] init];
num1 = [checkset mutableCopy]; //checkset is of type NSSet
num2 = [NSArray arrayWithArray:NoShows];
num3 = [NSSet setWithArray:num2];
[num1 minusSet:num3];
copy of NSMutableSet returns a NSSet
In your sample:
NSSet *immutableSet = [checksetM copy]; // returns immutable copy
-(NSSet *)ContainsNoShow:(NSMutableArray *)checkset
{
NSSet *newcheckset = [[NSSet alloc] init];
newcheckset = [NSSet setWithArray:NoShows];
NSMutableSet *checksetM = [NSMutableSet setWithArray:checkset];
[checksetM minusSet: newcheckset];
return checksetM;
}

What is the different between NSArray Parsing?

What is the difference between of Parsing in the following code segments.
which codes segments is faster in Parsing?
NSArray *arr = [[NSArray alloc] initWithObjects:#"Apple",#"Macbook", nil];
NSMutableArray *data = (NSMutableArray *)arr;
(and)
NSArray *arr = [[NSArray alloc] initWithObjects:#"Apple",#"Macbook", nil];
NSMutableArray *data = [NSMutableArray arrayWithArray:arr];
You have the same mistake in both snippets, you allocate memory for the object, and then assign something else to data, which makes you lose the previous (and have memory leak), e.g. this:
NSMutableArray *data = [[NSMutableArray alloc] init];
data = [NSMutableArray arrayWithArray:arr];
should be
NSMutableArray *data = [NSMutableArray arrayWithArray:arr];
Now for the question itself:
The first case is a bad idea, you cast the NSArray, but you canot modify it, as you didn't really changed its type, only assigned it to NSMutaleArray pointer.
The second case will create a new NSMutableArray which is mutable, with the contents of the NSArray, and this is cool, you may alter this array now.
It looks like what you want is either:
NSArray *arr = [[NSArray alloc] initWithObjects:#"Apple",#"Macbook", nil];
NSMutableArray *data = [arr mutableCopy];
or:
NSMutableArray *data = [[NSMutableArray alloc] initWithObjects:#"Apple",#"Macbook", nil];

Objective C How to fill rangeOfString of a NSArray?

I wonder if it is possible to fill rangeOfString objects of a NSArray. Because I have a long list of objects for after rangeOfString:
NSArray biglist´s count is higher than list´s count.
I want to filter away the objects from the small list of the main list.
Please tell me if this is not clear.
My codes below:
NSArray *biglist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"smalllist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
for (NSString *listword in list);
NSMutableArray *wordlist = [[NSMutableArray alloc] init];
NSMutableArray *worindex = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
NSMutableDictionary *mutdic = [[NSMutableDictionary alloc] init];
NSMutableArray *mutarray = [[NSMutableArray alloc] init];
for (NSString *s in mainlist)
{
NSRange ran = [s rangeOfString:listword];
if (ran.location !=NSNotFound)
{
//my codes here
}
}
EDIT:
I think I can solve this by writing
int i;
for (i = 0; i<[list count]; i++)
{
NSString *same = [list objectAtIndex:i];
NSLog (#"listword: %#", same);
}
But I am not sure where to place it, inside the for loop s in mainlist or outside.
EDIT: This for loop works inside the main for loop.
EDIT:
Tried these codes, but it doesnt work somehow..
NSArray *list = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"small" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSArray *mainlist = [[NSArray alloc] initWithArray:
[[NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"mainlist" ofType:#"txt"]
encoding:NSUTF8StringEncoding error:NULL] componentsSeparatedByString:#"\n"]];
NSMutableArray *large = [NSMutableArray arrayWithArray:mainlist];
NSArray *newlarge;
for (NSString *listword in list)
{
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"(SELF beginswith[c] %#)",listword];
newlarge = [large filteredArrayUsingPredicate:predicate];
}
NSLog (#"large: %#", newlarge);
NSLog (#"finished!");
"I want to filter away the objects from the small list of the main list."
If I understand correctly, you want to remove an array of items from another array. You don't want to do that much work and allocations inside an n^2 loop.
This removes an array of items from another array. Depending on how large your array is you may need to optimize further but this works:
NSArray *small = [NSArray arrayWithObjects:#"three", #"two", nil];
NSMutableArray *large = [NSMutableArray arrayWithObjects:#"one", #"two", #"three", #"four", nil];
[large removeObjectsInArray:small];
// print
for (NSString *current in large)
{
NSLog(#"item: %#", current);
}
This outputs:
2011-10-13 08:39:21.176 Craplet[5235:707] item: one
2011-10-13 08:39:21.178 Craplet[5235:707] item: four
I figured it out by myself and solved this :)
It works almost perfectly.
My codes:
NSArray *big = [[NSArray alloc] initWithObjects:#"hello ->mache", #"heisann hoppsann ->hiya", #"nei men ->da", #"however ->what", #"may ->april", #"mai ->maj", nil];
NSArray *small = [[NSArray alloc] initWithObjects: #"heisann ", #"nei men ", #"however ", #"mai", nil];
NSMutableArray *smallwithh = [[NSMutableArray alloc] init];
NSMutableIndexSet *mindexes = [[NSMutableIndexSet alloc] init];
for (NSString *same in small)
{
NSLog (#"listword: %#", same);
for (NSString *s in big)
{
NSRange ran = [s rangeOfString:same];
if (ran.location !=NSNotFound)
{
[smallwithh addObject:s];
NSUInteger ind = [big indexOfObject:s];
[mindexes addIndex:ind];
}
}
}
NSLog (#"smallwith: %#", smallwithh);
[smallwithh release];
NSMutableArray *newWords =[NSMutableArray arrayWithArray: big];
[newWords removeObjectsAtIndexes: mindexes];
[big release];
[small release];
NSLog (#"newWords: %#", newWords);

Comparing NSMutableArray Elements for Values

I am looking for a way to compare the contents of two NSMutableArray objects. Both arrays are filled with NSMutableDictionaries which were allocated separately but occasionally contain the same data.
Simplified Example:
NSMutableArray *firstArray = [[NSMutableArray alloc] init];
NSMutableArray *secondArray = [[NSMutableArray alloc] init];
NSMutableDictionary *a = [[NSDictionary alloc] init];
[a setObject:#"foo" forKey:"name"];
[a setObject:[NSNumber numberWithInt:1] forKey:"number"];
NSMutableDictionary *b = [[NSDictionary alloc] init];
[b setObject:#"bar" forKey:"name"];
[b setObject:[NSNumber numberWithInt:2] forKey:"number"];
NSMutableDictionary *c = [[NSDictionary alloc] init];
[c setObject:#"foo" forKey:"name"];
[c setObject:[NSNumber numberWithInt:1] forKey:"number"];
[firstArray addObject:a];
[firstArray addObject:b];
[secondArray addObject:c];
a, b and c are distinct object, but the contents of a and c match.
What I am looking for is a function / approach to compare firstArray and secondArray and return only b.
In Pseudocode:
NSArray *difference = [self magicFunctionWithArray:firstArray andArray:secondArray];
NSLog(#"%#",difference)
=> ({name="bar"; number=2})
Thank you in advance.
This can be achieved using NSMutableSet instances.
NSMutableSet * firstSet = [NSMutableSet setWithArray:firstArray];
NSMutableSet * secondSet = [NSMutableSet setWithArray:firstArray];
[firstSet unionSet:[NSSet setWithArray:secondArray]];
[secondSet intersectSet:[NSSet setWithArray:secondArray]];
[firstSet minusSet:secondSet];
NSLog(#"%#", firstSet);

How to copy last object of array to other array?

how would you copy the last object of a array and then add the object to some array. So in other words i want to take the last object of someArray and copy that lastObject to someArray2.
Thanks,
-David
NSArray *firstArray = [[NSArray alloc] init];
... populate firstArray ...
NSArray *secondArray = [NSArray arrayWithObject:[firstArray lastObject]];
or
NSArray *firstArray = [[NSArray alloc] init];
... populate firstArray ...
NSMutableArray *secondArray = [NSMutableArray alloc] init];
[secondArray addObject:[firstArray lastObject]];
or
NSArray *firstArray = [[NSArray alloc] init];
... populate firstArray ...
NSArray *secondArray = [[NSArray alloc] init];
NSArray *thirdArray = [secondArray arrayByAddingObject:[firstArray lastObject]];
Make sure everything is released as you now own all these references.
Edit: If you want a COPY everywhere there's [firstArray lastObject] change it to [[[firstArray lastObject] copy] autorelease] (thanks tc)