PDA

View Full Version : Using NSSelectorFromString in an If statement?




trey5498
Jul 1, 2008, 08:25 AM
I am attempting to check the state of checkboxes and then unselect them if they come back as selected, I have an array with all the the checkboxes listed in it. How ever I have an warning with the code: "Warning: invalid receiver type 'SEL'". I would think the next step would be to to set the checkbox to to unchecked. It would be something like correct?:



NSString *stTmp;
SEL aMethod;
for(i=0; i<[arrSelections count]; i++) {
stTmp = [arrSelections objectAtIndex: i];
aMethod = NSSelectorFromString(stTmp);
if([aMethod state]==NSOnState) {
[aMethod state]==NSOffState;
}
}



I have tried and get the same warning:


if([NSSelectorFromString(stTmp) state]==NSOnState)



Also how do I create a dmg file to contain all this and how do I get the NSTextView to be uneditable however still able to have info written to it through the code only?

Thank you again in advance



lee1210
Jul 1, 2008, 09:25 AM
From this other thread you started:
http://forums.macrumors.com/showthread.php?t=507041&p=5666918

You are not using the selector properly. The example in the other thread shows how to use performSelector: to run a method described by a SEL on an object. In this case, there is no Object, and you are trying to call a method on a SEL. I don't know what is in arrSelections, but what you are doing is not correct.

What is the name of the method you want to call?
What object do you want to call it on?
What are the parameters you need to pass?
What is in arrSelections? It appears that they are NSString type, but what are those strings?

It seems like perhaps your question was misunderstood in the last thread because of the way you wrote your example at the top. If arrSelections simply contains strings you want to pass as parameters to a method, you would just run something like:
[prninstall setupPrinter:stTmp];

This would call the method setupPrinter on an object called prninstall, passing a single NSString * as a parameter. I really don't think you need to be using selectors for the task at hand.

-Lee

Edit: I may have also misunderstood precisely what you're trying to do, but if you answer the questions about we should have a better idea. If arrSelections is supposed to have some GUI related objects that respond to state in it, for example, then that would change up the situation. I don't think in any case using a string you can get a reference to an Object in objective-C, but there may be some runtime methods that can use "reflection" to find this for you, but I don't think that's what you're trying to do.

robbieduncan
Jul 1, 2008, 09:28 AM
A selector is not an Object. It's simply a representation of the name of a method. It's not even linked to a specific class. What you are doing does not make the slightest amount of sense.

When you say "I have an array with all the the checkboxes listed in" what type are the objects in the array? I assume they are NSButton. In which case

stTmp = [arrSelections objectAtIndex: i];

will go wrong at run-time (and generate a warning at compile time) as the object returned will not be an NSString.


[aMethod state]==NSOffState;


makes no sense either. This will not set the state of the button. It will check that the current state is equal to NSOffState.

If the objects in arrSelections are NSButtons then you need to do this:

NSButton *button
for(i=0; i<[arrSelections count]; i++) {
button = (NSButton *) [arrSelections objectAtIndex: i];
if([button state]==NSOnState) {
[button setState:NSOffState];
}
}


Once again I say: go back to the start and learn the basics. This tiny amount of code contains so many errors it's amazing. You clearly don't know how:

1) Basic C works ([aMethod state]==NSOffState;)
2) Objective-C works (your attempt at using a Selector as an object)
3) Cocoa works

trey5498
Jul 1, 2008, 09:34 AM
I do have the basic idea of how it works, that is the problem. It is EXTREME basic and it was about 4 years + since I had to use it. I do plan on going back to the beginning after this project. I do appreciate you taking the time to point out the errors I am making.

How do I create a .dmg that will contain the drivers as well so I can put this out for testing atm?

robbieduncan
Jul 1, 2008, 09:36 AM
How do I create a .dmg that will contain the drivers as well so I can put this out for testing atm?

Do you have the rights to redistribute the drivers? Even if they are a free download from a website that does not give you the legal right to distribute them...

lee1210
Jul 1, 2008, 09:37 AM
Run Disk Utility.
Under File there is a "New" submenu. You can choose "Disk Image from Folder..." I believe (not at my Mac). You can choose whatever folder you would like and it will create a disk image. If you have drivers that need to be copied elsewhere you may want to build an installer, but that's a topic for a different thread.

As for the code, I looked again and it doesn't make much sense logically, either. From robbieduncan's example:

NSButton *button;
for(button in arrSelections) {
[button setState:NSOffState];
}


Checking the state of a button only to make them all off is not necessary. I may misunderstand something about how NSButtons work, but it seems like there would be a net zero change if the state was NSOffState and you set it to NSOffState.

-Lee

ElectricSheep
Jul 1, 2008, 09:42 AM
NSSelectorFromString returns a selector, which is not an object and you cannot send messages to it. You pass the selector to an object, and if the receiving object responds to that selector it will execute the corresponding method.

Going back to the original example I gave you:


NSString *stTmp;
SEL aMethod;

stTmp = [someArray objectAtIndex: 1]; //assuming this is an array of NSString objects
aMethod = NSSelectorFromString( stTmp ); //set the selector for the string

[prninstall performSelector:aMethod]; //send a message to prninstall to perform the selector


The key line here is [prninstall performSelector:aMethod]. That is the correct way to use selectors returned from NSSelectorFromString.

But,

It seems like you are trying to use an array of strings (perhaps the names of the buttons) to refer to a number of NSButton objects. This is incorrect, and you must use an array of pointers to the NSButton objects you want to manage. You don't need to use NSSelectorFromString() at all here.

robbieduncan
Jul 1, 2008, 09:46 AM
Checking the state of a button only to make them all off is not necessary. I may misunderstand something about how NSButtons work, but it seems like there would be a net zero change if the state was NSOffState and you set it to NSOffState.

That's perfectly true. If a button is alread in NSOffState setting it's state to NSOffState won't change anything.

lee1210
Jul 1, 2008, 09:55 AM
That's perfectly true. If a button is alread in NSOffState setting it's state to NSOffState won't change anything.

I figured, but didn't want to make assumptions about the behavior. I didn't know if a controller etc. would get messages when setState was called, resulting in a refresh of the control, etc. that may not be necessary. In that case, we can boil the original code down to one line if curly braces were omitted:

for(NSButton *button in arrSelections) [button setState:NSOffState];

Not the best style, but quite a bit more concise than the original assuming arrSelections is, in fact, and array of NSButton *s.

-Lee

trey5498
Jul 1, 2008, 10:34 AM
for(NSButton *button in arrSelections) [button setState:NSOffState];


Yields " *** -[NSCFString setState:]: unrecognized selector sent to instance 0x6344"

robbieduncan
Jul 1, 2008, 10:40 AM
for(NSButton *button in arrSelections) [button setState:NSOffState];


Yields " *** -[NSCFString setState:]: unrecognized selector sent to instance 0x6344"

OK so you have an array of NSStrings. Which are what exactly? Why do you have an array of strings? Where did this array come from. If it's the titles of the buttons then you are probably doing this entire thing wrong.

trey5498
Jul 1, 2008, 10:45 AM
it is the same title as the button outlets, when i add them to the array should it be added like:


[arrSelections addObject: NSButton "printername"];

atm:

[arrSelections addObject:@"printername"];


again I do very much apologize for my lack of knowledge and my general ignorance in Macs, but I am learning ;)

robbieduncan
Jul 1, 2008, 10:54 AM
Neither of those makes sense as a way to address the button in future. The first isn't even close to syntactically or even logically correct. The second seems to be adding a hard coded string. Again this doesn't make any sense.

If you have outlets for all the actual NSButton objects then use them. There is no direct way to turn a string into a pointer to a NSButton. The strings are totally useless to you for setting the state of the button.

By the way: In general this all seems to have been done the wrong way. If I want to add another printer to this how do I do it? Please don't tell me I open the nibs, add buttons then alter all the code? You should have a data model at the back with all the printers, details of them (what driver required etc) and controllers to link the model to the UI. This is a very basic Cocoa pattern. Not using it makes everything much harder (as you are finding).

lee1210
Jul 1, 2008, 10:54 AM
It would be something like:
NSButton *myButtonA = ...;
NSButton *myButtonB = ...;
[arrSelections addObject:myButtonA];
[arrSelections addObject:myButtonB];


-Lee

trey5498
Jul 1, 2008, 11:10 AM
If you have outlets for all the actual NSButton objects then use them. There is no direct way to turn a string into a pointer to a NSButton. The strings are totally useless to you for setting the state of the button.


This one totally slipped my mind and works. My problem is that I am trying to make things difficult at times. I am terribly sorry for the wasted time at times ;) I plan on building this thing as many different ways I can, reading the starter books from start to finish and even taking a class or two. This project is what is holding me back and I do thank you again for your patience.

yoavcs
Jul 2, 2008, 12:41 AM
Pardon the curiosity but I'm really perplexed.

You are trying to learn to fly a jet fighter plane by sitting in the cockpit and pressing the shiny red buttons.

Your questions display a lack of understanding of not only basic Obj-C and Cocoa, but general programming topics.

I don't mean that as an insult. Just an observation.

Drop this "project" of yours. Whoever gave it to you gave it to the wrong person. They asked someone who doesn't know a word in Russian to translate Dostoyevsky...

Grab a good book on C/Obj-C. Read it. Then progress to the Hillegass book on Cocoa if you want to do "Macs" programming as you call it. At this point you'll be a beginner, but you'll at least know the lingo and understand what all those shiny red buttons on the plane's console do.

You have to learn to crawl before you walk, and walk before you run.

There, I actually do feel better now. ;)

trey5498
Jul 2, 2008, 04:02 AM
I do appreciate the word of advice, however the project is all but done and the powers to be are all happy. The only thing left in this project are slight changes that needed to be done to it.

My problem was that I had a good grasp of college lvl C++ for windows (Visual s Studios style) that was 4 years old corrupted by every day usage of HTML,XML, and JavaScript in those four years. Place on top of that that I learned Perl in the same manner as this in about 2 weeks and I write complex Perl code to this day. They were not apparently expecting me to get this far in learning it. I do believe that I have learned alot by being thrown into the fire and believe it or not, I completely understand everything you guys have writen here as far as code.

If you want I can post a link to the finished code for critic and analyzes