billdoor
billdoor

Reputation: 2043

IOS NSMethodSignature stays nil

I recently started to develop for IOS and struggle with the Invocation Object.

What i have is a Class "Location", derived from NSManagedObject (it's part of the Coredata model)

@interface Location (CoreDataGeneratedAccessors)

- (void)addHasLocationInfoObject:(Info *)value;
...
@end

I also have other Classes that have similar signatures (addHasWorkorderInfoObject,...).

These InfoObjects have constraints with their "parent objects" in this case "Location" has several "LocationInfo" Objects, which i retrieve from a Database and want to add to the Location. Same thing should happen to all Objects that have InfoObjects assigned.

I am now trying to create a method that will work for any Object that sticks to the naming-conventions fixed by the project-documentation (Location -> addHasLocationInfoObject, XY -> addHasXYInfoObject ...).

My Approach for adding Infos to Objects now is:

-(void)setInfoForObject:(NSManagedObject *)managedObject withClass:(NSString *)className 
NSString *noteRefName = [[NSString alloc]init];
noteRefName = [NSString stringWithFormat:@"%@Info", className];
NSString *addInfoSelectorName = [[NSString alloc]init];
addInfoSelectorName = [NSString stringWithFormat:@"addHas%@Object::", infoClassName];

SEL addInfoPropertySelector = NSSelectorFromString(addInfoSelectorName);
NSMethodSignature *signature  = [[managedObject class] methodSignatureForSelector:addNotePropertySelector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];

[invocation setTarget:managedObject];
[invocation setSelector:addInfoPropertySelector];
[invocation setArgument:&note   atIndex:2];

However this gives me an Error, because the Signature object gets set to nil. I tried searching for the Problem and it seems to be related to the ":" in the Selectors' name.

But I do not understand how many and where and why i have to set these? I also seem to fail to find the Docs page that tells me how to do it properly.

Anny help appreciated, Thanks in advance!

PS. I Logged the SelectorName and the Classname and they both are spelled correctly.

Upvotes: 1

Views: 1361

Answers (1)

kovpas
kovpas

Reputation: 9593

Ok, I see multiple problems in your code. First of all, you allocate empty string instances and then immediately re-write them with new instances:

NSString *noteRefName = [[NSString alloc]init];
noteRefName = [NSString stringWithFormat:@"%@Info", className];

This is wrong. Correct way is:

NSString *noteRefName = [NSString stringWithFormat:@"%@Info", className];

There are two types of methods in ObjC: class methods and instance methods. If you don't know the difference, read about it here. So, the second problem is that you are trying to get a class method signature with methodSignatureForSelector: instead of getting instance method signature with instanceMethodSignatureForSelector:.

So, as far as I can tell, the correct way of re-writing this piece of code could be:

NSString *addInfoSelectorName = [NSString stringWithFormat:@"addHas%@Object:", infoClassName];
...
NSMethodSignature *signature = [[managedObject class] instanceMethodSignatureForSelector:addNotePropertySelector];

Upvotes: 2

Related Questions