NSMutableSet respondsToSelector addObject: returning false - objective-c

I'm having a problem with respondsToSelector with NSMutableSet.
I have a program like this:
NSArray *arguments = [[NSProcessInfo processInfo] arguments];
theClass = [arguments objectAtIndex: 1];
theMethod = [arguments objectAtIndex: 2];
theArgument = [arguments objectAtIndex: 3];
id object = [[NSClassFromString(theClass) init] autorelease];
if([object respondsToSelector:NSSelectorFromString(theMethod)]) {
NSLog(#"Result: %#",
[object performSelector:NSSelectorFromString(theMethod) withObject: theArgument]);
} else {
NSLog(#"Class %# doesn't respond to %#.",
theClass, theMethod);
}
I call it using ./program NSMutableSet addObject: str, but the program always says that NSMutableSet doesn't respond to addObject:.
I don't know why respondsToSelector always says that NSMutableSet doesn't respond to addObject. It's the same with ./program NSMutableSet allObjects.

You were checking something completely different...
[NSClassFromString(theClass) init]
needs to be
[[NSClassFromString(theClass) alloc] init]
instead.

Related

ABMultiValueCopyArrayOfAllValues Potential leak of an object

I'm trying to fix "Potential leak of an object". I have warning on
NSArray *phones = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(ABRecordCopyValue(person, kABPersonPhoneProperty));
and same on
NSArray *phones = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(ABRecordCopyValue(person, kABPersonPhoneProperty));
Xcode saying:
Call to function 'ABRecordCopyValue' returns a Core Foundation object with a +1 retain count
Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1
I dont understand how fix it.
-(BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person{
NSString *firstName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonFirstNameProperty);
NSString *lastName = (__bridge NSString *)ABRecordCopyValue(person, kABPersonLastNameProperty);
NSString *fullName = #"";
if (firstName != nil) {
fullName = [fullName stringByAppendingString:firstName];
}
if (lastName != nil) {
fullName = [NSString stringWithString:[fullName stringByAppendingString:#" "]];
fullName = [NSString stringWithString:[fullName stringByAppendingString:lastName]];
}
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:fullName];
[contactsArray addObject:tempArray];
_userNameTextField.text = [tempArray objectAtIndex:0];
CFRelease((__bridge CFTypeRef)(firstName));
CFRelease((__bridge CFTypeRef)(lastName));
NSArray *phones = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(ABRecordCopyValue(person, kABPersonPhoneProperty));
NSArray *emails = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(ABRecordCopyValue(person, kABPersonEmailProperty));
if (phones) {
[tempArray addObject:[phones objectAtIndex:0]];
}
else{
[tempArray addObject:#"No phone number was set."];
}
if (emails) {
[tempArray addObject:[emails objectAtIndex:0]];
}
else{
[tempArray addObject:#"No e-mail was set."];
}
// Now add the tempArray into the contactsArray.
_mobPhoneTextField.text = [tempArray objectAtIndex:1];
_emailTextField.text = [tempArray objectAtIndex:2];
[[contacts presentingViewController] dismissViewControllerAnimated:YES completion:nil];
return NO;
}
You have to split
NSArray *phones = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(ABRecordCopyValue(person, kABPersonPhoneProperty));
into separate commands so that you can release the object returned by ABRecordCopyValue():
CFTypeRef values = ABRecordCopyValue(person, kABPersonPhoneProperty);
NSArray *phones = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(values);
CFRelease(values);

Can't add objects to a NSMutableArray

So I have the following code:
NSMutableArray *array
array=[[NSMutableArray alloc] init];
[array addObject: object1];
[array addObject: object2];
NSLog(#"%#",array);
When I use the app in my iPod connected to my Mac, NSLog writes just null, I don't get object1 object2. What am I doing wrong?
PS: array is a property in .h #property (nonatomic, retain) NSMutableArray *array;
Should it be:
array=[[NSMutableArray alloc] init];
Your [[NSMutableArray array] init] should be [[NSMutableArray alloc] init]. That would work but its not a proper way to initialize objects. You didn't post what your array is, i assume you declared it wrong. It should be a pointer to a NSMutableArray object. Here is a working code:
NSMutableArray *array=[[NSMutableArray alloc] init];
[array addObject: #"a"];
[array addObject: #"b"];
NSLog(#"%#",array);
You are not initializing your array at all, that's why it doesn't return anything.
array=[[NSMutableArray alloc] init];
[array addObject: object1];
[array addObject: object2];
NSLog(#" Array is:%#",array);
Remember to release it afterwards(unless you are using ARC)
You could try doing it in one line.
NSMutableArray *array = [[NSMutableArray alloc] arrayWithObjects:#"a", #"b", nil];
NSLog(#"%#",array);
You declared array as a property. Its corresponding iVar gets initialized to nil.
So in your init method you have to initialize it:
Assuming you used
#synthesize array;
In your init method
if (self) {
//other init stuff
array = [[NSMutableArray array] retain];
}
Then when adding stuff
[self.array addObject: object];
Also note that he objects you put in there have to be properly initialized and r not nil.
So try to log this too
NSLog("the object %# was put in array. Array contains: %#",object, self.array);
And in dealloc, release your array!

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);

Strange __block storage variable crash

I have a problem in my code which I have distilled down to the following (silly) example
NSArray *array = [NSArray arrayWithObjects:#"1", #"2", #"3", nil];
__block NSString *a = #"-1";
[array enumerateObjectsUsingBlock:^(id whoCares, NSUInteger idx, BOOL *stop) {
a = [NSString stringWithFormat:#"%# %d", a, idx];
NSLog(#"%#", a);
}];
NSLog(#"%#", a);
This code works, but if I comment out the first NSLog (within the block) the code crashes. But, if I change the format string to the following
a = [NSString stringWithFormat:#"%d", idx];
then the code runs fine without the NSLog within the block.
What is going on here? I hope I am just misunderstanding something.
stringWithFormat: gives you an autoreleased object, which you're not retaining. By the time the block exits and you call NSLog, a might have already been deallocated.
One solution might be to use a mutable string and append to it each time instead of reassigning.
NSArray *array = [NSArray arrayWithObjects:#"1", #"2", #"3", nil];
NSMutableString *a = [NSMutableString stringWithFormat:#"-1"];
[array enumerateObjectsUsingBlock:^(id whoCares, NSUInteger idx, BOOL *stop) {
[a appendFormat:#" %d", idx];
}];
NSLog(#"%#", a);

objective-c function is not executed well

This function is not executed well.
-(void)sampleItemA:(NSString*)a itemB:(NSString*)b itemC:(NSDate*)c{
NSLog(#"A");
NSArray* ary = [[NSArray alloc] initWithObjects:a, b, c, nil];
NSLog([ary description]);
NSLog(#"B");
}
log
[Session started at 2009-11-07 20:46:10 +0900.]
2009-11-07 20:46:19.170 xxx[2374:207] A
What is the cause?
EDIT:
I tried.
But it not executed.
-(void)sampleItemA:(NSString*)a itemB:(NSString*)b itemC:(NSDate*)c{
NSLog(#"A");
NSArray* ary = [[NSArray alloc] initWithObjects:a, b, c, nil];
NSLog(#"%#", [ary description]);
NSLog(#"B");
}
log
[Session started at 2009-11-07 21:25:37 +0900.]
2009-11-07 21:25:48.738 xxx[2455:207] A
It is generally unwise to pass nonconstant format strings into NSLog, things get wonky. Try:
-(void)sampleItemA:(NSString*)a itemB:(NSString*)b itemC:(NSDate*)c{
NSLog(#"A");
NSArray* ary = [[NSArray alloc] initWithObjects:a, b, c, nil];
NSLog(#"%#", [ary description]);
NSLog(#"B");
}
I change NSArray to NSMutableArray.
It is executed.
-(void)sampleItemA:(NSString*)a itemB:(NSString*)b itemC:(NSDate*)c{
NSLog(#"A");
NSArray* ary = [[NSMutableArray alloc] init];
[ary addObject:a];
[ary addObject:b];
[ary addObject:c];
NSLog(#"%#", [ary description]);
NSLog(#"B");
}