PDA

View Full Version : issues passing string to another method




trey5498
Dec 16, 2011, 01:41 PM
I am grabbing a username from a NSTextField and then passing it to another method for processing. This installs printers.

How I am sending it from AppController.m:
[arrInstalled addObject:objc_msgSend(prninstall, NSSelectorFromString(stTmp), NSSelectorFromString(username))];

In PrnInstall.h
- (NSString *)Printer1: (NSString *)stUser;

in PrnInstall.m

- (NSString *)Printer1: (NSString *)stUser;
{
NSLog(@"stUser = %@", stUser);
return;
}


but I get unrecognized selector sent to instance and hangs? Did I pass the variable wrong?



chown33
Dec 16, 2011, 01:46 PM
Post the complete text of the actual error message. Copy and paste it. Do not paraphrase it.

Why are you calling objc_msgSend() directly? If the reference is a real Objective-C object, you should be able to use the [obj message] notation. If the reference isn't a real Objective-C object, objc_msgSend() is unlikely to work.

You're not showing enough code to decipher what to expect. In particular, you haven't shown either of the strings that are being converted to selectors.

Please explain what you're trying to accomplish. Not how you're trying to accomplish it. Just the what.

trey5498
Dec 16, 2011, 02:01 PM
The actual objc_msgSend() works fine. The main form is a list of printers (3 of them) and the stTmp is the printer name or the class in the method (i think I got that name right)

IE:

prnintall:

- printer1{
}

- printer2{
}

- printer3 {
}

The username will be used in each class. The issue is not an actual error at all. It is what the NSLog prints out: unrecognized selector sent to instance 0x102126070

chown33
Dec 16, 2011, 03:01 PM
The issue is not an actual error at all. It is what the NSLog prints out: unrecognized selector sent to instance 0x102126070

Is that the complete actual message? Nothing before it? Nothing after it?

It looks like an error message to me. Specifically, an error message from an exception, thrown because you are sending an unrecognized selector to an instance. That instance seems to have an object pointer of 0x102126070.

I don't see any NSLog in any of your posted code. Please explain what you mean. Do you mean you have an NSLog of the object, perhaps using %@, and that NSLog is producing the message shown? Well why not post that code? Do you realize that %@ requires the target object to implement a -description method? Which if your target object isn't really an object, poses a conundrum.


And you still haven't shown enough code to diagnose anything.

Do you realize that you're sending a dynamic message? I.e. from a selector chosen at runtime? This suggests that we need to see what the string is that's being converted into a selector.

It would also be nice to see the type of prninstall. Actually, it would be nice to see a well-isolated test case, written as a compilable program, so someone other than you can actually compile it, run it, and see the problem firsthand.

Without seeing types of variables, and not being able to see what the contents of any of your string variables are, you're asking an impossible task. You're asking us to debug your code without knowing even the most rudimentary information about it: no types, only fragments of code.

Plus you're using an advanced technique, with no other information on what you've done to debug this yourself, or whether you even wrote this yourself. At the very least, I would expect someone using such a technique to know the rudiments of debugging, and how to provide information.

Getting Answers (http://www.mikeash.com/getting_answers.html)
What Have You Tried? (http://WhatHaveYouTried.com/)

gnasher729
Dec 16, 2011, 03:30 PM
I am grabbing a username from a NSTextField and then passing it to another method for processing. This installs printers.

How I am sending it from AppController.m:
[arrInstalled addObject:objc_msgSend(prninstall, NSSelectorFromString(stTmp), NSSelectorFromString(username))];


Sending a message by using NSSelectorFromString is asking for trouble. As you have found out. Among other things you have the problem that the compiler doesn't have a chance to check whether the string can be converted to some sensible message selector, and that it doesn't have a chance to check the parameters that you are sending with that message.

So I would ask you to very carefully check what parameters you are sending, and whether they match the parameters that are expected.

gnasher729
Dec 16, 2011, 04:20 PM
Sending a message by using NSSelectorFromString is asking for trouble. As you have found out. Among other things you have the problem that the compiler doesn't have a chance to check whether the string can be converted to some sensible message selector, and that it doesn't have a chance to check the parameters that you are sending with that message.

So I would ask you to very carefully check what parameters you are sending, and whether they match the parameters that are expected.

By the way, the thread title is wrong. You aren't passing a string to another method.

trey5498
Dec 16, 2011, 08:09 PM
By the way, the thread title is wrong. You aren't passing a string to another method.

I dont have time to post the code t the moment, but i guess i got the backwards? Classes are the .m files and the methods are the indiviual sections? You will have to forgive me as I work for a major university and do alot of programming in other languaes, visual basic, perl (main language), html, java script ....... I only program in cocoa/objective-c when needed and i am modifing my last program (that i created 4years ago).

Since i wont have the code in front of me until tommorrow, i will y to explain a little better. The send command is in a loop that will take an array and set the current printer to strTmp (which is also the name of the method in prnInstall.m). We just switched from using lpr to ipp with the username being the port, so i had to add a text field to obtain the username.

So i am trying to not use a global variable, so i am attempting to use the same send command. Since I kinda need this quickly (end of next week) I am hurried when it comes to reminding myself.

The NSLog(@"stUser is: %@", stUser); is located in the printer1 method as a way to see how the program hangs (which no error shows and I have to close manually). The application build successful with no errors and no warnings. I got the "error" message after I added the NSLog to see what stUser equals. I assume it is because I sent the string wrong.

I hope this explains a little better and I will add the code tommorrow. Basically, how to I pass the NSString?

jiminaus
Dec 16, 2011, 09:13 PM
You're not passing a string, you're passing a selector.


[arrInstalled addObject:
objc_msgSend(
prninstall,
NSSelectorFromString(stTmp),
NSSelectorFromString(username)
)
];

trey5498
Dec 16, 2011, 09:26 PM
You're not passing a string, you're passing a selector.


[arrInstalled addObject:
objc_msgSend(
prninstall,
NSSelectorFromString(stTmp),
NSSelectorFromString(username)
)
];


If i change NSSelectorFromString(username) to NSString(username) it should work correct?

trey5498
Dec 16, 2011, 10:23 PM
I got access to the code a little early as I want to finish this up. Changing it to NSString as I asked is not it, well at least not that simple.

AppController.m (not the only code, but the rest shouldn't be relevant.

// calls the install file according to the correct OS version, hides the overview screen and shows a progress bar to show the progress
[prnOverview orderOut:nil];
[prnProcessing makeKeyAndOrderFront:self];
[prnProgress setIndeterminate:NO];
for(i=0; i<[arrPRNint count]; i++) {
//sets the length of the progress in time according to the count of arrPRNint array and updates the display until finished
[prnProgress setDoubleValue:100*i/(double)[arrPRNint count]];
[prnProgress displayIfNeeded];
stTmp = [arrPRNint objectAtIndex: i];

if([stDvrChk isEqualToString:@"Tiger"]) {
[arrInstalled addObject:objc_msgSend(prninstall104, NSSelectorFromString(stTmp))];
}
else {
[arrInstalled addObject:objc_msgSend(prninstall, NSSelectorFromString(stTmp), NSString @username)];
}



PrnInstall.m

- (NSString *)Printer1: (NSString *)stUser;
{
NSLog(@"New form: user name is = %@", stUser);
//NSString *sysPort = [NSString stringWithFormat:@"lpadmin -p AT-LAB-BW_1_SIDED -v ipp://server/ipp/%@ -E -P /System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/PrintCore.framework/Versions/A/Resources/Generic.ppd", stUser];
//system(sysPort);
PRNinstalled = @"Printer_1_SIDED";
return PRNinstalled;
}



If you need anything else to see my intent, please let me know.

jiminaus
Dec 16, 2011, 10:53 PM
NSString @username

This syntax doesn't make any sense. What is username? Is it an NSString*?

gnasher729
Dec 17, 2011, 06:24 AM
If i change NSSelectorFromString(username) to NSString(username) it should work correct?

There's nothing like trying.

But try to look at it with a bit of logic: What kind of parameter does the method expect? Therefore, what kind of parameter should you give it? And what kind of parameter are you actually giving it?

Now I'll tell you something that might shock you, but might _really_ help you: I have the impression that you got to a state where you are just fluffing about and trying things and hope that they work while actually not having the slightest clue what you are doing. It's Saturday today. So what if you just go to developer.apple.com, find the Objective C manual, and spend two days reading and writing little examples until you have a grasp of the language? And remove that bloody objc_msgSend call, because you frankly are not advanced enough to use it - as is demonstrated by your posts.

mduser63
Dec 17, 2011, 11:46 AM
And remove that bloody objc_msgSend call, because you frankly are not advanced enough to use it - as is demonstrated by your posts.

Really, do this. I have a fairly good understanding of Objective-C including the runtime, and I've never personally run into a need to call objc_msgSend() directly. You certainly don't need to be, and shouldn't be calling it directly. There are other red flags in your code that indicate you don't really know what you're doing, but this is a huge one.

chown33
Dec 17, 2011, 12:21 PM
If you need anything else to see my intent, please let me know.

Post the declaration of the 'username' variable.

Post the declaration of the 'stTmp' variable.

Post the declaration of the 'prninstall' variable.

By declaration, I mean the point in the code where you have something like one of these:
id stTmp;
NSString * username;
SomeOtherClassname * prninstall;

Those are possible examples. Your typename may be different. I'm just guessing, because you haven't posted anything that includes any variable declarations at all.


Your posts are confusing because you've used at least two distinct names for the method you intend to call. The code suggests its name is "Print1:", yet your descriptions refer to it as "print1" or "printer1". You also have at least one case where you posted code-like text that uses "print1", but it's unclear if this is real code or not.

Not only is the case different (Objective-C is case-sensitive), the spelling different (print1 isn't printer1), but there is a big difference between a method that takes parameters (and has colons) and one that doesn't.


In this code fragment, if you put an NSLog as shown, exactly what output is produced:
[prnProgress displayIfNeeded];
stTmp = [arrPRNint objectAtIndex: i];

NSLog( @"stTmp: %@", stTmp );

if([stDvrChk isEqualToString:@"Tiger"]) {

Frankly, this might not work. I'm guessing that stTmp is an object type, and not something else. This is one reason I keep asking for the declarations of the variables: to see what types they are.

Objective-C is a typed language. There are distinct types, and arbitrary conversions don't always occur automatically. It's not like JavaScript where the type of variables can change according to context.