<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Karl Kraft &#187; TheCodeBook &#8211; Fundamentals</title>
	<atom:link href="http://www.karlkraft.com/index.php/category/thecodebook-fundamentals/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.karlkraft.com</link>
	<description>Just a 2 bit programmer in a 64 bit world</description>
	<lastBuildDate>Thu, 24 Jun 2010 14:20:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Wandering Polygon Walkthrough</title>
		<link>http://www.karlkraft.com/index.php/2008/04/23/wandering-polygon-walkthrough/</link>
		<comments>http://www.karlkraft.com/index.php/2008/04/23/wandering-polygon-walkthrough/#comments</comments>
		<pubDate>Wed, 23 Apr 2008 08:24:23 +0000</pubDate>
		<dc:creator>Karl Kraft</dc:creator>
				<category><![CDATA[TheCodeBook - Fundamentals]]></category>

		<guid isPermaLink="false">http://www.karlkraft.com/?p=53</guid>
		<description><![CDATA[A walkthrough on how Wandering Polygon works across multiple monitors.]]></description>
			<content:encoded><![CDATA[<p>This post is for those developers who want to have a better understanding of how to write screen savers that smoothly flow between two or more monitors.</p>
<p><span id="more-53"></span><br />
To make this short enough to be readable, I&#8217;m going to assume you have already read through the documentation from Apple on how to write a normal screen saver.</p>
<p>Other than the generic project cruft, WanderingPolygon is 3 source files.  </p>
<p>The first,  WanderingPolygonViewPart.[h,m], is the original 1991 version that was written for NeXTSTEP.  This isn&#8217;t even compiled, it is just there for completeness sake.  An interesting note is that when I originally wrote this my NeXT workstation was black and white (well gray scal actually).  I shipped the color ramp on faith, and didn&#8217;t actually see it in color until months later, when I was visiting NeXT and saw it running by chance  on someone&#8217;s workstation.</p>
<p>When the screen saver kicks in, a full screen window is placed on top of all the other windows, and the primary view of that window is the screen saver view.  This is repeated for each monitor.  So if you have 3 monitors you will have 3 windows, and 3 separate views.   This is why screensavers don&#8217;t span multiple monitors without some extra coding.  </p>
<p>The most fundamental part of that coding is to divide the state or model from the view, or screen real-estate.  This is why there are 2 remaining source files.  WanderingPolygonView.[h,m] is the &#8220;view class&#8221;, a subclass of ScreenSaverView that every screen saver needs to inherit from.   However instead of having the drawing code or drawing state in this class like in a normal screen saver, the drawing and state code is in WanderingPolygon.[h,m], the &#8220;state&#8221; class.</p>
<p>I&#8217;ll start with View subclass</p>
<p><code></p>
<pre>
//
//  WanderingPolygonView.h
//  WanderingPolygon
//
//  Created by Karl Kraft on 4/22/08.
//  Copyright 1991-2008 Karl Kraft. All rights reserved.
//
...

typedef enum _ViewType {
	VT_Unknown=0,
	VT_Preview,
	VT_MainScreen,
	VT_AuxScreen
} ViewType;
</pre>
<p></code></p>
<p>Because this same code needs to work in both the preview pane, on the main screen and the auxiliary screens we have a define so that each instance can discover which of the 3 cases it represents.</p>
<ul>
<li>VT_Preview &#8211; an instance of the view acting as a small preview inside the preference pane
<li>VT_MainScreen &#8211; an instance of the view when running as a true screen saver.   This instance is on the main screen
<li> VT_AuxScreen &#8211; any other instance in screen saver mode that isn&#8217;t on the main screen.
</ul>
<p><code></p>
<pre>
//
//  WanderingPolygonView.m
//  WanderingPolygon
//
//  Created by Karl Kraft on 4/22/08.
//  Copyright 1991-2008 Karl Kraft. All rights reserved.
//

....
WanderingPolygon *sharedPolygon = nil;

- (id)initWithFrame:(NSRect)frame isPreview:(BOOL)isPreview
{
...
	localPolygon = [[WanderingPolygon polygonInRects:&#038;r count:1] retain];
...
}
</pre>
<p></code><br />
When running in screen saver mode, each monitor will have a separate instance of WanderingPolygonView.  However these views need to share the same underlying state, a common polygon.   It might be tempting to try to stick this singleton somewhere, but the screensaver needs to deal properly with changes in monitor arrangement or presence, something the state object can&#8217;t really detect.</p>
<p>When running as a preview we don&#8217;t want to use that shared polygon, because we want the previous version to be limited to the small frame of the preview area.  Hence we create a &#8220;localPolygon&#8221; for the preview case.<br />
<code></p>
<pre>

- (void)computeViewType;
</pre>
<p></code><br />
This method is called only once per instance, and determines what the ViewType is for this particular instance so that drawing can be adjusted accordingly.<br />
<code></p>
<pre>
	if (self.window.screen == [[NSScreen screens] objectAtIndex:0]) {
		cachedViewType = VT_MainScreen;
....
		[sharedPolygon release]; sharedPolygon = nil;
		sharedPolygon = [[WanderingPolygon polygonInScreens] retain];
</pre>
<p></code></p>
<p>Since there is no easy hook for a screen saver to determine when the &#8220;screensaving&#8221; is ending, we need a hook to reset the polygon.  Since we can&#8217;t do this when the saver ends, it is done the next time a view is created for the main screen.  The main screen view can be detected by seeing if the frame of the saver view is The purpose of this code is to recreate the polygon whenever the screen saver terminates.  </p>
<p>You might be tempted to use [NSScreen mainScreen] to get the &#8220;main screen&#8221;, but the &#8220;mainScreen&#8221; is not the one with the menu bar.  </p>
<p><code></p>
<pre>

- (void)drawVersionInfo;
...
- (void)drawDebugInfo;
</pre>
<p></code><br />
Both of these draw a small string in the bottom left of the window.  drawDebugInfo can be useful if you want to understand the relationship between the view frames, and the frames of the window containing each view.<br />
<code></p>
<pre>

- (void)drawRect:(NSRect)rect
{
	if (cachedViewType == VT_Unknown) [self computeViewType];
</pre>
<p></code><br />
If we haven&#8217;t figure out what kind of view we are, now is the time to do so.<br />
<code></p>
<pre>
	if (!backCleared) {
		[[NSColor blackColor] set];
		NSRectFill([self bounds]);
		backCleared = YES;
		[self drawVersionInfo];
	}
</pre>
<p></code><br />
The screensaver needs a black background, but we can only draw it once when the view is starting to draw.   After that the view will (by deisng)  just slap more and more color on the screen over the existing drawing.<br />
<code></p>
<pre>

	if (cachedViewType == VT_Preview) {
		[localPolygon draw];
</pre>
<p></code><br />
If a preview instance, just draw the local polygon<br />
<code></p>
<pre>

	} else if (cachedViewType == VT_MainScreen) {
		[sharedPolygon draw];
</pre>
<p></code><br />
If the main screen, draw the polygon as normal</p>
<p><code></p>
<pre>
	} else {
		NSGraphicsContext *savedContext= [NSGraphicsContext currentContext];
		CGContextRef ctx = [savedContext graphicsPort];
		CGContextSaveGState(ctx);
		CGContextTranslateCTM(ctx, 0-self.window.frame.origin.x, 0-self.window.frame.origin.y);
//		NSLog(@"translating %@",NSStringFromRect(self.window.frame));
		[sharedPolygon draw];
		CGContextRestoreGState(ctx);
</pre>
<p></code><br />
If an auxiliary screen perform a translation and then perform the same drawing as the main screen.  The resulting translation will make the image appear seamless between the two (or more) monitors.<br />
<code></p>
<pre>

- (void)animateOneFrame
</pre>
<p></code><br />
Some special code is needed here.  If you have 7 screens, this method will be called 7 times, once for each instance.  Therefore we test to make sure we are the main screen view or the preview instance and only then do we actually increment the state.</p>
<p><code></p>
<pre>
- (void)viewDidMoveToWindow;
...
- (void)viewDidMoveToSuperview;
...
- (void)setFrame:(NSRect)frameRect;
</pre>
<p></code><br />
Because of the way the preview instance is created and added to the window, some trapping is added here to detect when the view is re-added or re-selected, and when that happens the view is cleared to black. </p>
<p>Coming Soon&#8230;. the state class&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkraft.com/index.php/2008/04/23/wandering-polygon-walkthrough/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sound Picker Example Code</title>
		<link>http://www.karlkraft.com/index.php/2008/01/28/sound-picker-example-code/</link>
		<comments>http://www.karlkraft.com/index.php/2008/01/28/sound-picker-example-code/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 04:19:46 +0000</pubDate>
		<dc:creator>Karl Kraft</dc:creator>
				<category><![CDATA[TheCodeBook - Fundamentals]]></category>

		<guid isPermaLink="false">http://www.karlkraft.com/?p=45</guid>
		<description><![CDATA[after-action report for the Sound Picker sample code]]></description>
			<content:encoded><![CDATA[<p>Following up on the <a href="/index.php/2008/01/24/sound-picker-design/">Sound Picker Design</a>,  the completed example project along with the reusable classes are available in <a href="svn://svn.karlkraft.com/OneMinuteEggTimer">an SVN repository</a>, or you can download the <a href="http://www.karlkraft.com/wp-content/uploads/2008/04/oneminuteeggtimer.zip" title="OneMinuteEggTimer.zip">OneMinuteEggTimer.zip</a> file.</p>
<p><span id="more-45"></span><br />
In the end a couple of things differed from the original design. The sound example over the icon ended up being not needed because it was redundant once the sound plays when picked or the per sound volume is changed.</p>
<p>Setting it up in IB was not quite the chore I was worrying about, although final setup requires a few lines of code.  As a result I haven&#8217;t done an IB palette.  Perhaps this will be a later example.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkraft.com/index.php/2008/01/28/sound-picker-example-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sound Picker Design</title>
		<link>http://www.karlkraft.com/index.php/2008/01/24/sound-picker-design/</link>
		<comments>http://www.karlkraft.com/index.php/2008/01/24/sound-picker-design/#comments</comments>
		<pubDate>Thu, 24 Jan 2008 11:34:34 +0000</pubDate>
		<dc:creator>Karl Kraft</dc:creator>
				<category><![CDATA[TheCodeBook - Fundamentals]]></category>

		<guid isPermaLink="false">http://www.karlkraft.com/index.php/2008/01/24/sound-picker-design/</guid>
		<description><![CDATA[I was working on a project and needed to allow the user to pick a sound to play when an event occurs. Even though OS X has great sound support it lacks a common GUI element for allowing users to pick a sound to play. Each program implements this in a different way, and most [...]]]></description>
			<content:encoded><![CDATA[<p>I was working on a project and needed to allow the user to pick a sound to play when an event occurs. Even though OS X has great sound support it lacks a common GUI element for allowing users to pick a sound to play.  Each program implements this in a different way, and most of the sample code I looked at didn’t meet my expectations.  So I wrote this sound picker and example app to demonstrate how the picker can be used.<br />
<span id="more-15"></span></p>
<h3>Playing Sounds<br />
</h3>
<p>Playing a sound when a button is pressed is easy. In interface builder you drag the  sound file from the media palette to the button.  Whenever the button is pressed the sound will be played.</p>
<p>Why you would want a sound to be played every time a button is pressed is a bit of a mystery.  I suppose it would make sense if you wanted to build a quick sound board, but other than that this feature is pretty limited.</p>
<p>To play the sound programatically the code is pretty straight forward. </p>
<pre>
	NSSound *aSound = [NSSound soundNamed:@"Sosumi"];
	[aSound play];
</pre>
<p>There are only two caveats.  The first is that the sound name is case sensitive even though the file system may not be.  The second is that they sound must either have been created and named earlier in the application, or the sound must be in one of the following folders:</p>
<pre>
	~/Library/Sounds
	/Library/Sounds
	/Network/Library/Sounds
	/System/Library/Sounds
</pre>
<p>Three of those four folders don’t exist on a fresh install of OS X, and the one that does exist should never be edited lest it be overwritten on an upgrade or reinstall of the operating system.</p>
<p>Most users don’t know that they can add sounds by creating one of the 3 missing folders and filling it with aiff, wav, or mp3 files that can then be played as system sounds or accessed in dozens of applications.  </p>
<p>An application that requires the user to navigate out to finder to make the folders and then move files into the folders and then come back to the application to select the newly added item, that isn’t a very good user experience.  </p>
<p>Most applications also don’t automatically refresh when the user adds items to one of the sound folders.  Tracking changes to folders is easier under Leopard then it ever was under previous versions of OS X, but is still a complex task.  A quick look shows that System Preferences and iChat both require a quit and relaunch to recognize new sound files</p>
<h3>Desired Features<br />
</h3>
<p>For a good user experience with picking sounds I decided that four things were needed for my sound picker:</p>
<h4>The User Interface￼<br />
</h4>
<p><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/6efc7aa9-6c43-4f14-b490-cc79ddd142c3.jpg" alt="6EFC7AA9-6C43-4F14-B490-CC79DDD142C3.jpg" border="0" width="346" height="89" align="right" />I mocked up an example user interface using Snapz Pro to take some screenshots of various user interface elements and then cleaned them up in Photoshop.</p>
<h4>Drag and drop with copying<br />
</h4>
<p>I envision a scenario where the user has downloaded a clip from a web page and wants to use it in my application.  They should be able to drag the file from the downloads folders directly into the sound picker to use that sound, and the sound should continue to work even if they delete the original sound.</p>
<p>The well and file icon are there to visually cue the user that this is a place that might accept dragging and dropping of files.</p>
<h4>Popup of system sounds￼<br />
</h4>
<p><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/c318f65f-fd5a-4f9c-b826-fc7a466a7903.jpg" alt="C318F65F-FD5A-4F9C-B826-FC7A466A7903.jpg" border="0" width="126" height="223" align="right" />A list of system sounds, prebuilt sounds in my application, and sounds previously added to the sound picker should be nearby the drag and drop area. Within the popup they should be divided into sections, similar to what iChat does:</p>
<h4>Per sound volume control<br />
</h4>
<p>The user is more likely to have downloaded a sound then to have created it themselves.  That means if they have more than one sound in the application they are likely to end up from different sources and have a variety of loudness.  The sound picker should be able to set the volume on a per sound level.</p>
<h4>Sound example<br />
</h4>
<p>When a sound is set by either the popup or drag and drop, the user should get a sample of the sound, and be able to reproduce that sample if they want to hear it again.  That is what the play button does over the sound image to make it clear that it is going to play the sound in the well.  The button should not be there while accepting the drag, and should animate in after the drag.</p>
<h4>The Developer Interface<br />
</h4>
<p>The developer interface is as important as the user interface, because if it isn’t easy to develop with I’ll end up continuing to hard code sounds into my applications.  </p>
<p>The drag and drop view, and the controller object should be an Interface Builder palette so that I can use it in many applications.  It should  have binding to make it possible to use something other than a NSPopupButton or Slider for setting the volume.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkraft.com/index.php/2008/01/24/sound-picker-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Equality vs Identity</title>
		<link>http://www.karlkraft.com/index.php/2008/01/07/equality-vs-identity/</link>
		<comments>http://www.karlkraft.com/index.php/2008/01/07/equality-vs-identity/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 14:00:00 +0000</pubDate>
		<dc:creator>Karl Kraft</dc:creator>
				<category><![CDATA[TheCodeBook - Fundamentals]]></category>

		<guid isPermaLink="false">http://www.karlkraft.com/index.php/2008/01/07/equality-vs-identity/</guid>
		<description><![CDATA[A common tripup for programmers moving from other languages to Objective-C is dealing with the difference between equality and identity. This can be especially problematic because the rules for identity and equality are different depending on whether you are dealing with primitives or objects, and because FoundationKit can pull some tricks behind the scenes that [...]]]></description>
			<content:encoded><![CDATA[<p>A common tripup for programmers moving from other languages to Objective-C is dealing with the difference between equality and identity.    This can be especially problematic because the rules for identity and equality are different depending on whether you are dealing with primitives or objects, and because FoundationKit can pull some tricks behind the scenes that can confuse the understanding of equality and identity.</p>
<p>A simple conceptual model can make the difference pretty easy to grasp. </p>
<p><span id="more-23"></span></p>
<p>Imagine you have a pair of one dollar bills. Both bills are “equal”, because you could use either bill to pay for a one dollar item.</p>
<p>They are however not identical.  Each bill has a unique serial number that indicates when and where it was made.  No two dollar bills have the same serial number.  If you told me the serial number of one of the bills, you could put in in a pile with thousands of other bills and I would still be able to uniquely identify that particular bill.</p>
<p>
Now imagine the same test with coins instead of dollar bills.  While coins do have some slight variation (the year and pressing facility may vary), I can easily aquire a bag of 1000 quarters, all of which are not only equal but identical.  There is no way to identity a particular quarter once it has been thrown in a pile of identical quarters.</p>
<p>Objects (NSObject, NSView, etc) are like dollar bills, each one is unique but may be equal to others.  Primitives (int,float,char) are like coins, if they are equal they are identical.</p>
<p>With this in mind, I&#8217;ll now take you through a more long winded version&#8230;.</p>
<p><h2>Reading the Syntax<br />
</h2>
<p>
Now take a step back in time to before you were a programmer to a time when you are learning basic math.  You are presented with this mathematical phrase and this way of reading the phrase:</p>
<table border=1 width="100%" cellpadding=4 cellspacing=0>
<tr>
<td>Expression</td>
<td>Reads As:</td>
</tr>
<tr>
<td>a=b</td>
<td>a equals b</td>
</tr>
</table>
<p>
Once you start programming in a C language the “reading” of that changes, because the equal sign becomes an assignment operator, and the dual equal sign becomes the comparison for equality.</p>
<table border=1 width="100%" cellpadding=4 cellspacing=0>
<tr>
<td>Expression</td>
<td>Reads As:</td>
</tr>
<tr>
<td>a=b</td>
<td> a is assigned the value of b </td>
</tr>
<tr>
<td>a==b</td>
<td> a is equal to b </td>
</tr>
</table>
<p>
This works fine for C where the only types of variables are primitives like int, float, and char.  But in Objective-C there is both identity and equality.</p>
<table border=1 width="100%" cellpadding=4 cellspacing=0>
<tr>
<td>Expression</td>
<td>Reads As:</td>
</tr>
<tr>
<td>a=b</td>
<td> a is assigned the value of b </td>
</tr>
<tr>
<td>a==b</td>
<td> a is <b> identical </b> to b </td>
</tr>
<tr>
<td> [a isEqual:b] </td>
<td> a is <b> equal </b> to b </td>
</tr>
</table>
<p>
When it comes to objects: </p>
<ul>
<li> if <code>(a==b)</code> is true then it must follow that <code>([a isEqual:b])</code> is also true.
<li> However the opposite is not necessarily true.  If <code>([a isEqual:b])</code> is true, it does not mean that<code> (a==b)</code>, <em>although it may be the case even when you don’t expect it to be.</em>
</ul>
<h1>Source Code Based Examples<br />
</h1>
<p>You can download all the source code for these examples from <a href="svn://svn.karlkraft.com/equality">svn://svn.karlkraft.com/equality</a></p>
<h3>equality_01.m &#8211; primitive identity<br />
</h3>
<p>This first example uses primitives.  Sure enough, when compiled it outputs a single like that shows that both variables are equal.</p>
<pre>
//
//  equality_01.m
//  Equality
//
//  Created by Karl Kraft on 7/12/07.
//  Copyright 2007 Karl Kraft. All rights reserved.
//

int main(int argc, char **argv) {
  int a=4;
  int b=4;
  if (a==b) {
    NSLog(@"a is equal and identical to b");
  }
  return 0;
}
</pre>
<h3>equality_02.m &#8211; Object equality and identity<br />
</h3>
<p>The second example uses objects:</p>
<pre>//
//  equality_02.m
//  Equality
//
//  Created by Karl Kraft on 7/12/07.
//  Copyright 2007 Karl Kraft. All rights reserved.
//
#import <Foundation/Foundation.h>

int main(int argc, char **argv) {
  NSString *a=[NSString stringWithFormat:@"This is a string"];
  NSString *b=[NSString stringWithFormat:@"This is a string"];
  NSString *c=[NSString stringWithFormat:@"This is a longer string"];

  if (a==b) {
    NSLog(@"a is identical to b");
  }
  if (a==c) {
    NSLog(@"a is identical to c");
  }
  if ([a isEqual:b]) {
    NSLog(@"a is equal to b");
  }
  if ([a isEqual:c]) {
    NSLog(@"a is equal to c");
  }

  return 0;
}
</pre>
<p>When this example is run, only a single line is output, since a, b, and c are not identical at all, even though a and b have the same value.  </p>
<pre>2007-07-12 08:08:21.030 equality_02[8262:813] a is equal to b
</pre>
<h3>equality_03.m: Sometimes two different objects are really the same object and therefore identical.<br />
</h3>
<p>Example #2 was carefully crafted.  A slight change in example #3 produces results you may not expect. In this example we switch from using the method stringWithFormat: to using the method stringWithString:</p>
<pre>//
//  equality_03.m
//  Equality
//
//  Created by Karl Kraft on 7/12/07.
//  Copyright 2007 Karl Kraft. All rights reserved.
//
#import <Foundation/Foundation.h>

int main(int argc, char **argv) {
  NSString *a=[NSString stringWithString:@"This is a string"];
  NSString *b=[NSString stringWithString:@"This is a string"];
  NSString *c=[NSString stringWithString:@"This is a longer string"];

  if (a==b) {
    NSLog(@"a is identical to b");
  }
  if (a==c) {
    NSLog(@"a is identical to c");
  }
  if ([a isEqual:b]) {
    NSLog(@"a is equal to b");
  }
  if ([a isEqual:c]) {
    NSLog(@"a is equal to c");
  }

  return 0;
}
</pre>
<p>This small change results in a program with different output, even though you would seem to think that a is equal, but not identical to b.</p>
<pre>2007-07-12 08:19:52.994 equality_03[8529:813] a is identical to b
2007-07-12 08:19:52.995 equality_03[8529:813] a is equal to b
</pre>
<p>
In some particular cases identity comparisons for non mutable objects like NSString will return true because of an optimization performed by the compiler and by the Cocoa classes.  With this disparity between the second and third example, it is easy to see how a new programmer could get confused if they write a simple test application to compare two strings with the identity operator to test for equality, and find that is works.</p>
<p>
<img src="http://www.karlkraft.com/wp-content/uploads/2008/01/d35c0146-7570-448f-9052-5286fadbed34.jpg" alt="D35C0146-7570-448F-9052-5286FADBED34.jpg" border="0" width="164" height="81" align="right" />￼The first cause of this exception is the compiler/linker part of the tool chain.  To reduce memory usage if it finds two strings that are equal, it will only place one copy in the final binary, and have both variables point to the single instance of the string.</p>
<p>
The second is the way that non mutable instances of classes like NSArray, NSData, NSDictionary,  and NSString deal with making copies of strings.</p>
<table>
<tr>
<td><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/logo.gif" alt="logo.gif" border="0" width="18" height="18" align="left" /></td>
<td align="left">If a non-mutable NSString is created as a copy of another non-mutable NSString, instead of allocating memory and copying the value, the original string will be returned.  A similar rule applies for other classes like NSArrary, NSDictionary, and NSData that have both mutable and non-mutable variants.  If either the created or source object is mutable this rule does not apply.</td>
</tr>
</table>
<h3>equality_04.m: mutable and immutable copying<br />
</h3>
<pre>//
//  equality_04.m
//  Equality
//
//  Created by Karl Kraft on 7/12/07.
//  Copyright 2007 Karl Kraft. All rights reserved.
//
#import <Foundation/Foundation.h>

int main(int argc, char **argv) {
  NSString *a=[NSString stringWithString:@"This is a string"];
  NSString *b=[NSString stringWithString:@"This is a string"];
  NSMutableString *c=[NSMutableString stringWithString:@"This is a string"];
  NSString *d=[NSString stringWithString:c];

  if (a==b) {
    NSLog(@"a is identical to b");
  }
  if (a==c) {
    NSLog(@"a is identical to c");
  }
  if (a==d) {
    NSLog(@"a is identical to d");
  }
  if ([a isEqual:b]) {
    NSLog(@"a is equal to b");
  }
  if ([a isEqual:c]) {
    NSLog(@"a is equal to c");
  }
  if ([a isEqual:d]) {
    NSLog(@"a is equal to d");
  }

  return 0;
}

2007-07-12 08:53:34.872 equality_04[8891:813] a is identical to b
2007-07-12 08:53:34.874 equality_04[8891:813] a is equal to b
2007-07-12 08:53:34.876 equality_04[8891:813] a is equal to c
2007-07-12 08:53:34.878 equality_04[8891:813] a is equal to d</pre>
<p>Symbolically, the order of events in this program is something like this.  During the compile we have three embedded copies of the string @”This is a string”</p>
<div style="text-align:center;"><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/b2090bca-a7e9-4747-9970-aa8428bcdbc0.jpg" alt="B2090BCA-A7E9-4747-9970-AA8428BCDBC0.jpg" border="0" width="275" height="76" /></div>
<p>The linker then reduces these to a single instance of the string.</p>
<div style="text-align:center;"><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/93666ec5-68aa-40c9-aa06-7adf9bf2484a.jpg" alt="93666EC5-68AA-40C9-AA06-7ADF9BF2484A.jpg" border="0" width="150" height="17" /></div>
<p>When the program runs, NSString is asked to create a new string from that embedded constant, and this is assigned to the variable a.  Rather than create a new string, a just becomes a pointer to the original string. </p>
<div style="text-align:center;"><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/cefe1195-df2b-42dd-b109-17524ef99269.jpg" alt="CEFE1195-DF2B-42DD-B109-17524EF99269.jpg" border="0" width="275" height="76" /></div>
<p>The same step is repeated with the variable b.</p>
<div style="text-align:center;"><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/38cd14df-0807-4526-a6b6-a82df2342962.jpg" alt="38CD14DF-0807-4526-A6B6-A82DF2342962.jpg" border="0" width="275" height="76" /></div>
<p>When we get to the next like, c is made a mutable version of the string.  Since mutable versions can change over time, a new instance of the string is created, and c points to this instance.</p>
<div style="text-align:center;"><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/950e4c62-1cf1-4a18-8991-d7e4d6e30365.jpg" alt="950E4C62-1CF1-4A18-8991-D7E4D6E30365.jpg" border="0" width="278" height="76" /></div>
<p>Finally, d becomes a copy of c. Even though d is immutable, it is possible that the string c has been changed since the creation of the mutable version of the non-mutable shared instance.  So d becomes yet another instance of the string:</p>
<div style="text-align:center;"><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/dfb05307-e0ed-4cfc-8ec7-786a572df9ee.jpg" alt="DFB05307-E0ED-4CFC-8EC7-786A572DF9EE.jpg" border="0" width="281" height="81" /></div>
<p>Thus, a,b,c, and d are all equal, but only a and b are identical.</p>
<p>
Keep in mind that you should not rely on this behavior as it is particular to the implementation of NSString and various linker flags that may be turned on or off. </p>
<p>
That a and b are identical is the result of optimization.  It can change depending on compiler flags, whether a and b are in the same library or not, and on the implementation of NSString.  In future versions, NSMutableString may be smart enough to realize that is it an unmodified version of a non-mutable string, and therefore non-mutable copies of the mutable string would be identical to the original non-mutable string, and in that case a,b, and d would be identical.</p>
<p><table>
<tr>
<td><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/logo.gif" alt="logo.gif" border="0" width="18" height="18" align="left" /></td>
<td align="left">Always test for equality instead of identity unless:</p>
<ul>
<li>you are using primitives in which case equality is identity
<li>you really mean to test for absolute identity and not equality.
</ul>
</td>
</tr>
</table>
<h3>
example_05 &#8211; Sometimes equal objects aren’t equal unless they are identical<br />
</h3>
<p>Example #5 has a main function that creates two instance of MyCircle and comapres them for equality.  The comparison returns false even though it would seem that it should return true since the only state of the circles, the raidus, is identical in both.</p>
<pre>
//
//  main.m
//  Equality Example #5
//
//  Created by Karl Kraft on 7/12/07.
//  Copyright 2007 Karl Kraft. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MyCircle.h"

int main(int argc, char **argv) {

  MyCircle *a = [MyCircle circleWithRadius:10];
  MyCircle *b = [MyCircle circleWithRadius:10];

  if ([a isEqual:b]) {
    NSLog(@"a is equal to b");
  } else {
    NSLog(@"a is not equal to b");
  }
  return 0;
}

//
//  MyCircle.m
//  Equality Example #5
//
//  Created by Karl Kraft on 7/12/07.
//  Copyright 2007 Karl Kraft. All rights reserved.
//

#import "MyCircle.h"

@implementation MyCircle

- initWithRadius:(int)anInt;
{
  [self init];
  radius=anInt;
  return self;
}

+(MyCircle *)circleWithRadius:(int)anInt;
{
  MyCircle *aCircle=[[self alloc] initWithRadius:anInt];
  return aCircle;
}

- (int)radius;
{
  return radius;
}
@end
</pre>
<p>So why is a not equal to b? </p>
<p>
Because isEqual: method need to be written for each class.  Since MyCircle doesn’t implement isEqual, the superclass implementation in NSObject is used.  That implementation just return true if the objects are identical.</p>
<table>
<tr>
<td><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/logo.gif" alt="logo.gif" border="0" width="18" height="18" align="left" /></td>
<td align="left"> If your class is a direct subclass of NSObject and you don’t implement isEqual, then the test for equality is a test of identity </td>
</tr>
</table>
<p>
The reason for this behavior is that the author of NSObject isn’t really capable of determining whether any instance of a subclass you write in the future is truly equal to another instance.  Your two instances may have some state that is different yet doesn’t affect the equality.  For instance two arrays with the same objects but different capacities may be considered equal.  A mutable string and a non-mutable string are two very different classes but they are considered equal if the underlying string is the same.</p>
<p>
If you write a class that is going to need to be compared for equality then you should write an isEqual method.  And in most cases any subclass of NSObject will need an isEqual method.</p>
<p><table>
<tr>
<td><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/logo.gif" alt="logo.gif" border="0" width="18" height="18" align="left" /></td>
<td align="left"> Even though you may not be directly comparing two instances of your class, other classes will.  For example NSArrary when determining equality to a second NSArray asks each instance whether it is equal to the instance in the other NSArray.  Another example is NSSet which uses equality to determine whether you are allready in the set.
</td>
</tr>
</table>
<p>Along with implementing isEqual you should implement a hash method as well.  Many kit classes will use the hash method to determine whether it is possible for two instances to be equal.  </p>
<table>
<tr>
<td><img src="http://www.karlkraft.com/wp-content/uploads/2008/01/logo.gif" alt="logo.gif" border="0" width="18" height="18" align="left" /></td>
<td align="left"> Instances that are equal must have equal hash values.</p>
</td>
</tr>
</table>
<p>Example 6 shows an implementation of MyCircle.m that will work correctly.</p>
<pre>//
//  MyCircle.m
//  Equality
//
//  Created by Karl Kraft on 7/12/07.
//  Copyright 2007 __MyCompanyName__. All rights reserved.
//

....

- (BOOL)isEqual:(id)otherObject;
{
  if ([otherObject isKindOfClass:[MyCircle class]]) {
    MyCircle *otherCircle= (MyCircle *)otherObject;
    if (radius != [otherCircle radius]) return NO;
    return YES;
  }
  return NO;
}

- (NSUInteger) hash;
{
  return radius;
}

@end</pre>
<p>There are a couple of important points to keep in mind when implementing isEqual and hash.  </p>
<ul>
<li>Two instances that are equal must return the same hash.
<li>The hash method should be quick since it may be called often if your class is stored in an NSSet or NSHashTable.
<li> If you have more than a single piece of state, use the XOR operator to create the hash.  For example if your MyCircle class had an x and y location as well you could use:
<pre>
- (NSUInteger) hash;
{
  return radius ^ xLocation ^ yLocation;
}
</pre>
<li> If your have other objects as instance variables, use their hash to build your hash.  If you had a color and string associated with your MyCircle class you might use:
<pre>- (NSUInteger) hash;
{
  return radius ^ xLocation ^ yLocation
                ^ [myColor hash] ^ [myString hash];
}
</pre>
<li> Keep in mind that the method for equality is called “isEqual” and not “isEqualTo”.  A category of NSObject related to scripting declares a method called isEqualTo: which is a cover for isEqual.  But isEqualTo: is only called by the scripting engine.
<li> You can’t assume that the object passed to your isEqual: method will be another instance of your class, or even a subclass of your class.  So perform a test for class membership first thing in your method and then perform a cast once you are sure you are dealing with an instance of your class or subclass.
<li> Keep in mind that subclasses may end up calling [super isEqual:] to perform part of the equality test, so don’t write an implementation of isEqual: that assume both self and otherObject are of the exact same class.  This is why you should use isKindOfClass instead of  isMemberOfClass.
<li> Conversely, you may not want to call [super isEqual:] as part of your equality implementation, since you may be getting the NSObject implementation of identity instead of equality.   Always check the documentation and the implementors list, if you are subclassing some class other than NSObject and implementing isEqual:
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.karlkraft.com/index.php/2008/01/07/equality-vs-identity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
