• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSButton question
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSButton question


  • Subject: Re: NSButton question
  • From: Simon Stapleton <email@hidden>
  • Date: Sat, 10 Aug 2002 10:15:45 +0200

Subject: Re: NSButton question
Reply-To: email@hidden
From: "Lorenzo Thurman" <email@hidden>
Cc: email@hidden
Date: Thu, 8 Aug 2002 16:50:46 -0400 (EDT)

--- On Thu 08/08, The MACed wrote:
From: The MACed [mailto: email@hidden]
To: email@hidden
Date: Thu, 08 Aug 2002 09:10:15 -0700
Subject: Re: NSButton question

Mind posting some codes?
Like your action method of the button.

Here's my action method:
- (IBAction)changeText:(id)sender
{
if([myTextField stringValue] == @"Hello Cocoa World!")
[myTextField setStringValue:@"Hello Aqua World!"];
else
[myTextField setStringValue:@"Hello Cocoa World!"];
}

This is iffy, to say the least. You're comparing the values of the pointers, so unless [myTextField stringValue] returns _exactly_ the same object as @"Hello Cocoa World" happens to point to, this will not work in the way you expect it to. what you're looking for is

[[myTextField stringValue] isEqualToString: @"Hello Cocoa World"], which will compare the contents of the strings.

this should solve your problem, and make your code more readable than this:

Nothing special, just change the text field's label. Since my first message, I tried using awakeFromNib like this:
@implementation MyController
- (IBAction)changeText:(id)sender
{
NSString *tmp;

tmp = currentText;

(BTW, the following line is extraneous, and does nothing)
currentText = [myTextField stringValue];
[myTextField setStringValue:newText];
currentText = newText;
newText = tmp;
}


-(void)awakeFromNib{
currentText = @"Hello Cocoa World!";
newText = @"Hello Aqua World!";
}
@end

This works just fine, but I'd like to know why it does not work properly the first time?

This is a fairly common, and relatively understandable, mistake to make, and seems especially common in those coming from a C++ background (understandable, as in C++ you can, and frequently do, override operators)

In Objective-C, == is the standard C ==, and so does nothing more, and nothing less, than what is specified in K&R.

This is important, as it means that (assuming object1 and object2 are object pointers) object1 == object2 will only ever succeed if they point to exactly the same object. If we want to check for object equivalence, we need to use one of the selectors implemented by the class for that purpose.

As a side note at this point, it is useful to know that NSString is a class cluster. As such, although we may be referring to objects as having type NSString, they will in fact have some other type (a concrete subclass of NSString), and that you have (almost) no control over what type a particular string will have, and in almost all cases you don't care anyway. @"string", [NSString stringWithString:@"string"], etc will almost definitely not have the same type, nor point to the same object, and therefore @"string" == [NSString stringWithString:@"string"] will almost certainly fail.

So. what do we do?

Checking through the NSString documentation, we find -isEqualToString:, which is exactly what you need at this point. Note also that everything complying to the NSObject protocol (i.e. pretty much everything) also defines -isEqual: which is a more general comparison routine.

Another side note: In Objective-C, we have no method overloading. Thus, -isEqual: takes (id) as its parameter type, and must, in effect, route the query to a more specialised routine depending on the types of the compared objects. Those classes in Foundation requiring specialist handling of -isEqual: (Strings, Arrays, etc) have specialist handlers - -isEqualToString:, -isEqualToArray: etc, which are faster to use when you know the types you're comparing.

You can, of course, define your own -isEqual: in your own classes where you require specialist handling (modulo defining -hash as well, see the docs), but if you do it's worth considering defining -isEqualTo<MyClass>: as well, especially if you think your class might be used by someone else (frameworks, for example)

TFMs? -isEqualToString: (NSString documentation) and -isEqual: (NSObject protocol documentation), and == in Kernighan and Ritchie.

Hope that helps, and doesn't muddy the waters too much

Simon
--
PGP Key Id : 0x50D0698D
--
If the answer isn't obvious, the question is a distraction. Go find an easier question.


--
PGP Key Id : 0x50D0698D
--
Hot Water! Yes! Bath! : <http://www.tufty.co.uk/Move/index.html>
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: NSButton question
      • From: Ondra Cada <email@hidden>
  • Prev by Date: Re: Classes and the Production of Objects
  • Next by Date: Re: FTPClient Beta Released - Please test
  • Previous by thread: Re: NSButton question
  • Next by thread: Re: NSButton question
  • Index(es):
    • Date
    • Thread