Errata

Building Cocoa Applications: A Step by Step Guide

Errata for Building Cocoa Applications: A Step by Step Guide

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date Submitted
Printed Page 551
Step 2

PB has been replaced by XCode. The technique described to expose GraphPaper services requires adding a New Sibling to the build target. I have searched the XCode manual, and find no reference to Siblings, nor to creating services. Not quite sure how to proceed. Can anyone provide some help?

Anonymous  Nov 01, 2009 
Printed Page 314
Changing Target Information

I purchased this book several years ago - wanted to get back into it recently, and found that the updated OS required X code vs. Project Builder. Most of the functionality is the same, but there are many more choices in editing the target, and different terminology. I thought I covered the bases, but when I try to run the appication (step 66), I get a runtime error: MathPaper[1682] *** Uncaught exception: <NSInvalidArgumentException> *** +[MathDocument sharedApplication]: selector not recognized. How do I modify the additional fields in the Target Properties? Do I set both Type and Creator to MATP? Do I change the Executable option? Is the Principal Class MathDocument? What about the Store Type?

Anonymous  Aug 29, 2009 
Printed Page 342
point 10

see code on page 333

Looking further, the problem is that the line path=[[NSBundle mainBundle] pathForAuxiliaryExecutable=@"Evaluator"]; in windowDidLoad fails to work and returns null. That explains the error message triggered by setLaunchPath a few lines later. A workaround is to hardcode the path as an NSString.

I am not yet clear why pathForAuxiliaryExecutable fails to work.

Anonymous  Jul 04, 2008 
Printed Page 342
point 10

I got the same problem. Using old-fashioned debugging with printf I found the problem was the line [evaluator setLaunchPath:path]; in windowDidLoad in PaperController.m

Anonymous  Jul 04, 2008 
Printed Page iii
OFFICES table should link to USERS table, not ACCOUNT_TYPES

(iv) ROLES table should link to USER_ROLES

Anonymous   
Printed Page 1
1

The Smalltalk programming language is not spelled 'SmallTalk' but 'Smalltalk'

This error is made in several places.

Anonymous   
Printed Page 20
6. Modeless dialogs

Modeless dialogs are treated undifferently than "other windows" listed in #7.
They do NOT remain on top of document windows.

As an example try TextEdit and place a document window on top of the find
dialog.

(Mac OS X, v. 10.1.5)

Anonymous   
Printed Page 22
First sentence

"A dark gray disclosure triangle (>) at the right side of a menu cell ..."

When those triangular marks appear on menus, they are not called disclosure
triangles. A disclosure triangle is the same shape, but has a completely
different function and different behavior. When clicked, a disclosure
triangle rotates to point down (v) and reveals (discloses) more information.
Clicking again rotates it back to point right (>) and reveals less information.

Those symbols on menus do not share the same meaning or the same behavior,
and should not be called by the same name.

Anonymous   
Printed Page 32
Last paragraph under "Menu Structure"

"To see the contents of a menu, single-click on the menu name in the title
bar."

Menus are in the menu bar, not the title bar. The title bar is the thing at
the top of a window, the menu bar is the thing at the top of the main display.

Anonymous   
Printed Page 35
Step 12

"Only one application can be dropped into the Dock at a time."

This is not true as of Mac OS X 10.1.4. You can drop multiple items onto
the dock simultaneously.

Anonymous   
Printed Page 38
Figure 3-5

There seem to be many problems with this diagram.

(i) ATTENDEES table shouldn't have a USER_TYPE_ID field
(ii) ATTENDEES table should link to USERS table, not USER_TYPES

Anonymous   
Printed Page 41
Step 42

"In fact, you can switch the scrolling direction while pressing the mouse
button by simply sliding from one scroll arrow to the other."

As of Mac OS X 10.1.4, this only works in Cocoa apps.

Anonymous   
Printed Page 43
3rd paragraph

The last sentence in this paragraph begins with "Note that the keyboard
equivalents...". This sentence should refer to figure 1-32.

Anonymous   
Printed Page 59
Ex. 4

This is a difficult exercise to accomplish. I have always wondered if Apple's
implementation of services is buggy, or if particular apps don't handle
services.

For example, I can do Services:Grab:Selection in TextEdit, but not in Internet
Explorer. It would seem that only Apple Apps can be a client to services.
Can you show me a non-Apple App that can be a service client?

Obviously some services are context sensitive and require user action such as
highlighting text before using them.
**[59] Ex. 4;**
Oh, I get it. Services only work with Cocoa apps.

Anonymous   
Printed Page 82
step 15

The text says to click "Step over ..." (and the icon shown is for stepping
over) but then the text says: "This action steps out..." There's a different
icon to click for stepping out.

Anonymous   
Printed Page 82
Step 14. and 17.

"Font" window should be "Colors" window, of course.

Anonymous   
Printed Page 83
3rd paragraph

While it is interesting to see gdb running in Emacs, Emacs itself is not introduced
until page 108 and is very difficult for a novice to use. The introduction on page
108 should be moved to chapter 2 and a few Emacs commands mentioned; specifically,
how to get help and how to quit the program.

Anonymous   
Printed Page 89
Last paragraph

the bland window should probably be blank

Anonymous   
Printed Page 90
First paragraph

If a window is behind another window or closed, you can make it visible by
double-clicking its icon in the Nib file window.
Not entirely true. When you create a new IB palette project in PB and
double-click Testinspector.nib, the Inspector window is completely hidden
behind the IB Info panel and will stay that way however much you double-click
the Inspector window icon.

Anonymous   
Printed Page 93
Figure 3-7

Though the figure tries to label all of the items in the Views palette,
it omits labels for the AppleScript palette and the second NSBox (depicted
as a vertical line between the rounded NSButton and the NSTextViews).

Anonymous   
Printed Page 109
last paragraph

The programming language "Smalltalk" is spelled "Smalltalk" and not "SmallTalk".
There are several occurences of "SmallTalk" in the book.

Anonymous   
Printed Page 117
3rd paragraph

"This object is then sent an init method..." should read "This object
is then sent an init message...".

Anonymous   
Printed Page 118
1st large paragraph

The text says that a "class interface" is "a fancy name for an included
file that is brought to the compiler's attention with an #import directive,"
but the example which follows shows an import directive and a separate
class interface. This is confusing because the import directive in the
example is not explained. I think what is meant is that the example file,
which contains a class interface, will be brought to the compiler's attention
with an import directive in some other file. Then explain the import
directive in the example.

Anonymous   
Printed Page 123
1st code sample, methods -setStart: and setEnd

The code as given can lead to serious memory problems, and provoke an
application crash. This problem can happen if the object passed as
parameter to the methods is the same as the instance variable object.

The more correct approaching pattern (there are other solutions) is:

- (void) setStart:(id) anObject
{
[start autorelease];
start = [anObject retain];
}

Anonymous   
Printed Page 123
dealloc sample code

I am not sure if this is a technical mistake or not..

But in the over ridden -(void)dealloc routine, shouldn't
the last action call be to

[super dealloc]

and NOT
[super release]

It makes no sense to override the dealloc routine and then
call the parent's release routine to finish doing the
dealloc work..

so.. I think the proper code should be

-(void)dealloc
{
[start release] ;
[end release] ;
[super dealloc] ;
}

Anonymous   
Printed Page 123
First code sample block

The implementation of the two set methods shown does not work in some
special cases and will cause an application to show unpredictable results
depending on its use.

Precisely, the set methods do not work, if the argument passed in has
the same value as the instance variable (e.g. start) and the retain count
of the object referenced is one.

i.e. (start==anobject && [start retainCount]==1) yields YES.

What happens it that the start object is destroyed using -dealloc and retain is
called on that freed memory region.

Anonymous   
Printed Page 125
1st paragraph

The second sentence says "This variable is of type Class, which is a
typedef for an ANSI C structure..." This should read "This variable
is of type Class, which is a typedef for a pointer to an ANSI C structure...".

Anonymous   
Printed Page 125
Code snippet at bottom.

Code snippet begins "NSMutableString *str3 = [[NSString alloc] init];" It should
read "NSMutableString *str3 = [[NSMutableString alloc] init];" Otherwise, a run-time
error occurs.

Anonymous   
Printed Page 125
bottom code listing

The appendString: calls are missing the @ signs before the double-quotes.
It should read:

[str3 appendString:@"This is how you build "];
[str3 appendString:@"a Cocoa String"];

Without the @ signs this will generate a compiler error

Anonymous   
Printed Page 127
Box, second bullet

This one is related to the one on page 123:

i.e. (start==anobject && [start retainCount]==1) yields YES.

What happens it that the start object is destroyed using -dealloc and
retain is called on that freed memory region.

The sentence in the box ought to be some mantra to always remember.
However, it is inacurate, as "accessor method" means both set- and
get- methods. In order to be correct, it should say "set-methods"
or "setters".

Anonymous   
Printed Page 128
example 4-5

The line "NSAutoreleasePool ..." should be in bold.

Anonymous   
Printed Page 128
Example 4-5

The line that begins

NSString *str2 = ...

should be indented.

Also,

NSLog(@"The value of str1 is '%@'", str2);

should be

NSLog(@"The value of str2 is '%@'", str2);

That is, change str1 to str2.

Anonymous   
Printed Page 131
2nd paragraph ("After the autorelease pool is created....")

The paragraph says "... the program allocates an NSApplication object by sending the
alloc message ..." but the example shows the program creating the NSApplication
instance by sending the sharedApplication message. There is no [NSApplication alloc]
in the example.

Anonymous   
Printed Page 131
5th (last) paragraph

The text reads: "The event loop terminates when the NSApp object is
sent an NSApp or stop: message; this usually happens when the user
chooses the Quit menu command. The NSApp message causes NSApp to call
exit(), terminating the program. The stop: message causes [NSApp run]
to exit."

The first message should not be NSApp but rather terminate:. Thus the
text should read: "The event loop terminates when the NSApp object is
sent a terminate: or stop: message; this usually happens when the user
chooses the Quit menu command. The terminate: message causes NSApp to
call exit(), terminating the program. The stop: message causes [NSApp run]
to exit."

Anonymous   
Printed Page 131
inside the main() function

There is an inconsistency between the main() function listing of the
Tiny.m program on page 131 and the original one on page 107. The one
on page 131 is missing the line:

[NSApp release];

Anonymous   
Printed Page 131
2nd paragraph

In the second paragraph, there is the text "This object [refering to
NSApp] is create with the <b>sharedInstance</b> method, ...." In the
code sample, the "sharedApplication" message/method is used. Code seems
to run fine, and no 'sharedInstance' in NSApplication.h....

Anonymous   
Printed Page 132
First code section. 2nd paragraph on the page

Small snippet of Tiny.m code is reproduced for examination. When the Tiny.m code is
first introduced on pages 105-107, there is an inconsistency.

From the code for the setup function (listed at the bottom of page 106):
NSWindow *myWindow; // typed pointer to NSWindow object
NSView *myView; // typed pointer to NSView object
NSRect graphicsRect; // contains an origin, width, height

From the code listed on page 132:
NSWindow *myWindow = nil;
NSView *myView = nil;
NSRect graphicsRect;

Specifically, comments are not included on page 132, and NSWindow and NSView
are not initialized to nil in the complete code listing on pages 105-107.

Anonymous   
Printed Page 133
second code eg [myWindow code]

The third line of the code has styleMask: NSTitledWindowMask (etc.) here and in the
initial listing of the program on p.107. Further down p. 133, in the explanation of
the arguments, this appears simply as style: NSTitledWindowMask....

Anonymous   
Printed Page 135
3rd paragraph

It says that NSView is an abstract superclass and thus instances of NSView are
*rarely* used. If it's an abstract class, instances are *never* used.

Anonymous   
Printed Page 136
makeKeyAndOrderFront note (middle of page)

Not a mistake, but one answer to how to make the window be brought to the
front is to insert the following in main():
[NSApp unhideWithoutActivation]; //bring window to front

This should be inserted just before [NSApp run];

The result will be a front (but unactivated) window, which is Ok for this
example.

Anonymous   
Printed Page 136
3rd line from bottom

Should be

int n = 12;

not n=31 (see page 106)

Anonymous   
Printed Page 156
Step 14

when creating Actions. Step 14 refers to 'clearall:' and the 'A'
should be capitalized. The picture has it correctly and page 157 also
refers to it correctly but if someone where to follow the steps they
would create an error.

Anonymous   
Printed Page 156

when creating Actions. Step 14 refers to enterdigit and the 'd'
should be capitalized, this will cause problems in the resulting code. The
picture has it correctly and page 157 also refers to it correctly but if
someone where to follow the steps they would create an error.

Anonymous   
Printed Page 156
step 14

incorrect capitilisation of methods, should read:

14. Add the clearAll:, enterDigit:,

not

14. Add the clearall:, enterdigit:,

Anonymous   
Printed Page 160
and following pages

One of the important things programmers do is name things. The instance variables in
Calculator are poorly named. 'X' and 'Y' are uppercase, against social norms. They
would be better named 'operand' and 'total'. 'enterFlag' and 'yFlag' are named a bit
vague. Once you name things for what they do, you see how the algorithm is really
working. For example, the assignment Y = X; in enterDigit is redundant: it's always
going to have happened already in enterOp.

After renaming and tracing, I just had to rewrite the algorithm:

- (IBAction)clearAll:(id)sender
{
operand = total = 0.0;
operator = NONE; //(add this to enum and lose yFlag)
operandEntryToBeginFlag = YES; //enterFlag renamed
[self displayOperand];
}

- (IBAction)enterDigit:(id)sender
{
if (operandEntryToBeginFlag)
{
operand = 0.0;
operandEntryToBeginFlag = NO; //operand entry now begun
}

operand = (operand >= 0 ?
(operand * radix) + [[sender selectedCell] tag] :
(operand * radix) - [[sender selectedCell] tag]);
[self displayOperand];
}

- (IBAction)enterOperator:(id)sender
{

switch (operator)
{
case NONE: total = operand; break;
case ADD: operand = total += operand; break;
case SUBTRACT: operand = total -= operand; break;
case MULTIPLY: operand = total *= operand; break;
case DIVIDE: operand = total /= operand; break;
case EQUALS: total = operand; break;
default: //should never reach here
NSLog(@"Error: reached switch default in enterOperator");
[readout setStringValue: [NSString stringWithFormat: @"improper
operator"]];
return;
}
operator = [[sender selectedCell] tag]; //get the next operation

operandEntryToBeginFlag = YES; //ready to start entering the next operand

[self displayOperand]; //display the total (same as the operand for the moment)
}

Anonymous   
Printed Page 161
enterDigit method

In the enterDigit method, the calculation of the new X value does not
consider the sign of X. Hence, if you make X negative, and then add some
more digits, the value increases (closer to zero).

I changed the function to this

- (IBAction)enterDigit:(id)sender
{
double Z = [[sender selectedCell] tag];
if (enterFlag) {
Y = X;
X = 0.0;
enterFlag = NO;
}
X = (X*10.0) + (X >= 0 ? Z : -Z);
[self displayX];
}

I am having a lot of fun putting the calculator together. Cocoa is
pretty exciting technology.

In Chapter 6, I am curious what happens to the 'default' about box.
I added the new one, but there were no steps to delete the existing
one to recover its storage. Is the default part of the System?

Anonymous   
Printed Page 168
paragraph following step 16

"...the NSMatrix object will send the enterDigit: action message to an
instance of our Controller class."

Since there is just one instance of the Controller class, this reads
better if it says "... will send the enterDigit:" action message to
the instance of our Controller class."

Anonymous   
Printed Page 177
3 line

return self;

not consistent with same code on pp 161 where function exits after
[self display]

Anonymous   
Printed Page 179
Step 5

In this step we are told to fill in the appropriate tag values for each
of the recently added function buttons to the calculator interface.
Each of the tag values is supposed to correspond to the function enum
values created on page 177 (PLUS = 1001, SUBTRACT = 1002, ...). The
author forgets to mention what to do with the equal sign button "=" --
it has no enum value.

Figure 5-28, which is on the same page as this step, hints at the solution.
(It shows the equal sign as having the tag value '1005'). The text,
however, fails to mention it.

Anonymous   
Printed Page 181
2nd paragraph

When you implement doUnaryMinus, you must modify one line of enterDigit:

X = (X >= 0 ?
(X * radix) + [[sender selectedCell] tag] :
(X * radix) - [[sender selectedCell] tag]);

Otherwise, the user may change the sign to minus and continue entering the operand
and the calculator will malfuntion.

Anonymous   
Printed Page 185
middle paragraph

The text says the NSApplication() function "loads the applications's
main nib file (MainMenu.nib in Calculator)" but the NSApplication()
function shown above that paragraph does not refer to "MainMenu.nib"
(it refers to "myMain").

Anonymous   
Printed Page 185
Last paragraph of first section.

The text states that main() recieves the return code from NSApplication().
The code example shows that its return type is 'void,' however. Either
the statement incorrect, or it warrants further explanation.

Anonymous   
Printed Page 193
middle paragraph

The text says "(Recall that we parsed an outlet from the Controller.h
file into IB in the previous chapter; here we'll parse a method in a
similar fashion.)" In fact, in the previous chapter we did not parse
an outlet -- we parsed a method (page 181).

Anonymous   
Printed Page 195
3rd Paragraph. 4th sentence.

The first letter (the lowercase m) of the method name makeKeyAndOrderFront:
is not emboldened according to the formatting conventions used through the
book.

Anonymous   
Printed Page 203
Step 35 in making the Calculator App

Here's what you get for running out and buying Jaguar before these fine authors could
revise their book:

Bring up the File's Owner information as decribed in the text. Here's where we start
to deviate from the text. The way to inform File'sOwner that is of the Controller is
by finding it under the Custom Class screen not the Attributes screen of the File's
Owner Info dialog. Follow the instructions in the book to make AboutPanel.nib of the
Controller class. Just do not go by Figure 6-16. I compiled and it worked.

Anonymous   
Printed Page 205
"Adding Icons to Applications section"

"For example, the Mail program uses the icon containing an envelope
(shown at the edge of the page)..."

It's a stamp, not an envelope.

Anonymous   
Printed Page 206
references an onlamp article. The URL is

incorrect -- the substring "muc" in it should be "mac" -- also, it
should probably point at a oreillynet.com front door instead of
onlamp.com.

http://www.oreillynet.com/pub/a/mac/2001/05/24/aqua_design.html

Anonymous   
Printed Page 210
Step 5

When dragging the icn file to the Images group, the little gray arrow
does not change colors. Instead, the triangle twists and the group
folder opens.

Anonymous   
Printed Page 211
Step 14

If the AboutPanel.nib is not visible in IB, double-click AboutPanel.nib
in the PB's Groups and Files pane.

Anonymous   
Printed Page 213
middle paragraph

Oh, where to begin? This section about images really needs clarification,
perhaps a whole page. The text says to drop an image file in "a nib
window in IB or in the main window in PB." Are the results of those two
actions identical, or are they entirely different? The following sentence
seems to indicate that they are different ("images that are stored in one
nib cannot easily be used by objects in other nibs"), yet when dragging an
image to one nib window the image is accessible in the other nib (under
its Images tab). Also, when dragging an image to a nib, a dialog appears
asking if the image should be added to the project. So, it appears that
the two actions are the same. (I'm using PB 1.1.1 and IB 2.2.)

Also, it appears that dropping an image file in PB only leaves a reference
(alias?) because deleting the image in the groups window of PB asks about d
eleting the reference. What happens then if the original image file is
moved or altered?

Images appear to be stored in the project folder. Where are the sounds,
where'd they come from?

How to delete (unused) images or sounds from a nib? Should we?

Anonymous   
Printed Page 213
middle paragraph

The text says to drop an image "in the main window in PB." What is the
main window? I find that an image can only be dropped in the "Groups
and Files" window, and even then the user must drag it in to desired
location within the list of files. (PB 1.1.1.)

Anonymous   
Printed Page 219
First paragraph under "Modifying the Controller Class"

In the first sentence:

"To make the Controller work with this new NSMatrix that contains a
pop-up menu, ..."

Do you really mean to say 'NSMatrix', or did you mean to say 'NSButton'.
We haven't added an NSMatrix to the application since adding the function
buttons; but we have just added a pop-up menu, and that is a type of NSButton.

Anonymous   
Printed Page 221
Step 23, case: 16

The format string for base 16 should be @"%X" and not @"%x" so that the hex digits
will be displayed in upper case.

Anonymous   
Printed Page 225
Section on delegation

This section would benefit by a diagram showing how objects delegate messages and
which object talks to which other objects, etc. In general, the entire book would be
better if there were a few diagrams showing how object and windows relate, how
actions and outlets operate, etc.

Anonymous   
Printed Page 229
Step 4

In step 4 the Controller class interface reads "Controller:Object". This is wrong, it
should be "Controller:NSObject".

Anonymous   
Printed Page 230
Paragraph after the figure 7-10

The direction of the connection seems counter-intuitive since the information flow
(the initial value of the popup) is from the popup to the Controller. I guess
"information flow" is the wrong way to think about this (aren't we dealing with
references here?), but I lack the mental image of how this works. Please explain
further in the text.

Anonymous   
Printed Page 231
4th paragraph (i.e. step 10 code to type in)

The first line of bold is:

@interface Controller(NSApplicationNotifications)

but should be:

@interface Controller(ApplicationNotifications)

That is the category name should match in the Category.h and Category.m files.

Anonymous   
Printed Page 234
first paragraph

"Refer to the Cocoa Foundation documentation." This is not the first place this
phrase appears. A brief description of how to navigate in PB to the documentation
based on a highlighted selection in the code would be useful.

Anonymous   
Printed Page 235
3rd code listing

In the line:

id cell = [cellList objectAtIndex: i];

"cellList" should be "cells"

Anonymous   
Printed Page 236
N/A

The "applicationDidFinishLaunching" delegate method is not updated to disable keypad
buttons that are not applicable for the given radix. "Works" using the default base-
10, but if has a different default radix is specified in IB, the keypad is incorrect
on startup.

Can't just call the setRadix as implemented from the delegate....

Anonymous   
Printed Page 238
Step 5.

The autosizing of the function keys should not match that of the readout, but rather
that of the digit button matrix. That is, if they should remain anchored to the
bottom, as in Figure 7-15.

Anonymous   
Printed Page 240
setRadix: method

Why not declare ysize to be a float? Both NSSize and NSRect have fields that are
floats, and ysize is used in calculations with the fields of these structs.
Although declaring it to be a double doesn't hurt, it leaves me wondering why.

Anonymous   
Printed Page 260
entire chapter on events

I'm repeating myself here, but the discussions of keyboard events and event chains in
general (in addition to objects and messages) just cry out for some diagrams. For
example, look at pages 224 and 225 in Aaron Hillengass's "Cocoa Programming for Mac
OS X".

Anonymous   
Printed Page 265
step 7, last sentence

You must Control-click on the CalcWindow subclass, not just anywhere in the nib
window.

Anonymous   
Printed Page 269
last line

In checkView, I believe there is a more straightforward way (and indeed, a more
robust way in this case) to test the class, as follows:
if ( [aView isKindOfClass: [NSMatrix class] ] ) {
could be simplified to:
if ( [aView class] == [NSMatrix class] ) {

and on page 270:
if ( [aView isKindOfClass: [NSButton class] ] ) {
easier:
if ( [aView class] == [NSButton class] ) {
If my logic is not equivalent or better, then the text could explain why.

Anonymous   
Printed Page 270
checkView method, calls to [self checkButton/checkMatrix: aView]

Two warnings when compiling the Calculator app in Chapter 8. To remove the warnings
and match the downloadable code, in the 'checkView' method, the aView parameter
passed to 'checkMatrix' and 'checkButton' needs to be cast to the type of the method
parameters: (NSMatrix *) and (NSButton *), respectively.

Anonymous   
Printed Page 270
and next page

If you want to investigate special characters (delete key, enter, etc.) put this in
your keyDown method:

NSLog([theEvent characters]);

Also, see NSEvent.h.

Then implement them in your checkButton method:

if (@selector(clearAll:) == [aButton action])
{
//clear key (note capital %C for unicode!)
[keyPressTable setObject: aButton
forKey: [NSString stringWithFormat: @"%C",
NSClearLineFunctionKey]];
//delete key
[keyPressTable setObject: aButton
forKey: [NSString stringWithFormat: @"177"]];

//escape key
[keyPressTable setObject: aButton
forKey: [NSString stringWithFormat: @"33"]];

} else if ([title isEqualToString: @"="])
{
//enter key for equals
[keyPressTable setObject: aButton
forKey: [NSString stringWithFormat: @"03"]];

//return key for equals
[keyPressTable setObject: aButton
forKey: [NSString stringWithFormat: @" "]];

//equals for equals
[keyPressTable setObject: aButton forKey: title];

} else if ([title isEqualToString: @"w"])
{
//option forward slash for division (change your nib to w)
[keyPressTable setObject: aButton forKey: title];

//forward slash for division
[keyPressTable setObject: aButton
forKey: [NSString stringWithFormat: @"/"]];

} else if (1 == [title length] && [aButton isEnabled])
{
[keyPressTable setObject: aButton forKey: [title uppercaseString]];
[keyPressTable setObject: aButton forKey: [title lowercaseString]];
}

Anonymous   
Printed Page 271
1st word on that page

The 1st word in this page is "NSButtons".
It should be "NSCells".

Anonymous   
Printed Page 272
2nd paragraph

Describing the performClick: method, the last sentence in this paragraph says "The
message is not sent if the on-screen button is disabled." It looks as though the
message is indeed sent, but the button doesn't respond to it if it is disabled.

Anonymous   
Printed Page 273
first footnote

In addition to the compiler warning discussed in the footnote, there are also
warnings in the checkView method as follows:
[self checkMatrix: aView];
passing arg 1 of `checkMatrix:' from incompatible pointer type
[self checkButton: aView];
passing arg 1 of `checkButton:' from incompatible pointer type
these can be fixed by adding (NSMatrix *) and (NSButton *) casts, respectively, as
follows:
[self checkMatrix: (NSMatrix *)aView];
[self checkButton: (NSButton *)aView];
Or, an (id) cast could be used in both cases.

Anonymous   
Printed Page 276
top of page

In addition to the errors in the Calculator code itself (that are fixed in the
exercises), there appears to be some errors in the nibs (indicated by the little
yellow "!" attached to the instances icons). In my case, the "MainMenu" instance of
MainMenu.nib shows "One of the children has a bad/missing connection") and the
"File's Owner" instance in both nibs show "unconnected outlet".

Anonymous   
Printed Page 276
Exercises

Suggestion. Other good exercises would be to program the Delete key to delete the
least-significant digit from the calculator display and the Return key to perform the
"=" function. Also, how about adding an RPN mode?

Anonymous   
Printed Page 288
4th entry in Table 9-2

"ATS" stands for "Apple Type Services" and not "Adobe Type Server". The ATSServer is
a separate process that registers plugin scalers (like the TrueType and Type 1
scalers), and maintains a cache of rendered glyphs which it provides to clients. This
prevents the same glyphs from having to be hinted and rendered separately for every
process in the system.

Anonymous   
Printed Page 290
Exercise 5

The exercise suggests examining the "vmstat" command in the Terminal. I haven't
checked every possible version of OS X, but in 10.1.4 the command is spelled
"vm_stat", and does not take the parameters described in the exercise.

Anonymous   
Printed Page 302
1st paragraph (after example)

Text recommends using Control-C (interrupt) to abort the program. It's both more
elegant and more correct to use Control-D to generate an end-of-file, which
terminates the input and the program cleanly.

Anonymous   
Printed Page 305-307
in the

section "Changing the Names of MathPaper Project Files" I found that the
steps for renaming
files can be simplified. Also, an important step was left out that
subsequently causes a bug.

* All the steps described requiring one to go to the Finder and renaming
folders can more easily be done within Project Building using the menu
item Project -> Rename. Using this method also changes the names of the
files and directories in the file system and obviates the need to delete
and add files in Project Builder.

* A bug is introduced if a change in the Info.plist file of the Products
folder is not made. The string "MathDocument" replaces "MyDocument" and
should read as:

<key>NSDocumentClass</key>
<string>MathDocument</string>

Omitting this step results in the application not being able to create a
new document.

Anonymous   
Printed Page 307
Changing the Names of MathPaper Project Files, after point 26

It's necessary to change the NSDocumentClass in the Application Settings from
"MyDocument" to MathDocument".

Without this the built program reports it can't create a window when it's run.

User needs to select the "Target" tab, and select "MathPaper" in the left pane. From
there, a "Application Settings" tab appears in the right pane. Select that, click on
the "Expert" button, and open the CFBundleDocumentTypes array. Open entry 0 and
change the value of "NSDocumentClass" from "MyDocument" to "MathDocument".

While this is a minor error, the complexity of finding where to correct it is beyond
the grasp of anyone who hasn't done it previously!

Anonymous   
Printed Page 311
Figure 10-8

The screenshot is missing the "Show All" menu item below the "Hide Others" menu item.

Anonymous   
Printed Page 311
Step 38

Step 38 on page 311 says to remove the space below the Preferences menu. The image
shown in Figure 10.8 includes this space, going against the last sentence in step 38:
"Your MathPaper application menu should now look exactly like the one in Figure 10-8."

Anonymous   
Printed Page 314
Between step 45 and 50 the

order is wrong (49 right after 46?)

Anonymous   
Printed Page 314
Step 49

The 'Identifier' field is found under 'Basic Information'. As Step 49 is between a
number of steps in the 'Document Types' setting groups, it is a little confusing.
(Note: This is with PB 2.0 April 2002 beta.)

Anonymous   
Printed Page 327
steps to buid executable location

My PB is 2.0.1

the command:

[NSBundle mainBundle] pathForAuxiliaryExecutable: @"Evaluator"

look at Contents folder (that is build/MathPaper.app/Contents in our example}

>From PB I cannot move to Contents folder of product. No bar line shown up

It may be PB2.0.1 change the GUI layout, I I cannot find "New Build Phase -> New Copy
Files Build Phase command"

Anonymous   
Printed Page 328
Step 28 and next paragraph

Step 28 says to "Drag the recently added Evaluator executable into the Resources
group," and the following paragraph after Step 29 says that Figure 11-8 should list
Evaluator as both a resource and a product. It is only listed as a Produt in the
Figure.

Anonymous   
Printed Page 330
Step 9: Type Command-1 (not Command-5) and change...

(see also unofficial errata dated 5/22/2002:

Anonymous   
Printed Page 330
Step 3 and 4 (and elsewhere)

Searching for the NSWindowController class is not a good suggestion, it is much
easier and faster to select it in the Pop-Down menu.

Subclassing from the Classes menu is less efficient than simply use the context menu
directly over the NSWindowController listing. This also goes for creating new outlets
and actions, as well as reading declaration files and creating new files, of course.

Anonymous   
Printed Page 333
The last paragraph of the page refers to the first and third lines of

- (void)windowDidLoad method; the paragraph should refer to the first and
fourth lines.

Anonymous   
Printed Page 339
text

Another way to get lastLine with two lines of code:

NSArray *paragraphs = [[theText string] componentsSeparatedByString: @"
"];
NSString *lastLine = [paragraphs objectAtIndex: [paragraphs count] - 2];

Anonymous   
Printed Page 341
Step 8.

A space is missing between NSMakeRange(len,0) and the second parameter -
withString:str

Anonymous   
Printed Page 341
Second paragraph

The second paragraph, which attempts to explain the steps
in the gotData: code, has a small error. The sentence that
starts "The third statement..." indicates an autorelease is
done on the variable "str". In fact, that is NOT done at
all, and instead the "str" variable is forced released at
the end of the method instead.

That sentence should be removed, and a new sentence inserted
at the end of the paragraph with something like "Finally, we
release the storage for the str variable to not cause
a memory leak" .

Anonymous   
Printed Page 342
point 10.

While this may not really qualify as Errata, I found the following problem:

After succcessful compilation the program failed to show any document windows,
reporting

2006-11-05 18:40:16.290 MathPaper[10718] *** -[NSCFDictionary setObject:forKey:]:
attempt to insert nil value

in the Run Log window.

The same happened with the code downloaded from the web site so I will assume some
incompatibility with newer versions of XCode (I am running 2.4 right now).

As I just started Cocoa programming using this book I feel unable yet to figure out
what might have gone wrong and would appreciate any hints on how to proceed ...

Anonymous   
Printed Page 342
point 10

Using old-fashioned debugging with printf I found the problem was the line [evaluator setLaunchPath:path]; in windowDidLoad in PaperController.m

see code on page 333

Looking further, the problem is that the line path=[[NSBundle mainBundle] pathForAuxiliaryExecutable=@"Evaluator"]; in windowDidLoad fails to work and returns null. That explains the error message triggered by setLaunchPath a few lines later. A workaround is to hardcode the path as an NSString.

I am not yet clear why pathForAuxiliaryExecutable fails to work.

Anonymous   
Printed Page 344
Step 22

The bold text indicates that the code goes in the AUTORELEASE
method, yet it plainly goes in the dealloc method.

Also, the code sample shown for the dealloc method is NOT
the correct one. It is missing the statement:

[ [ NSNotificationCenter defaultCenter ] removeObserver: self ] ;

which should go before the [evaluator termiante]. The proper
code for dealloc should look like:

// Clean up resouces when we are done with a MathDocument
- (void)dealloc
{
[ [ NSNotificationCenter defaultCenter ] removeObserver: self ] ;
[evaluator terminate] ;
[evaluator release] ;
[super dealloc] ;
}

Anonymous   
Printed Page 356
RTF.h @implementation code

In the RTF.h file, the dealloc method is declared but
this is not needed since we are sub-classing from NSObject
which has it defined already, similar to our override
of init().

Anonymous   
Printed Page 357
in the -data method

In order to avoid memory leakage, data2 shoud be autoreleased.

Thus, the last line should be:

return [data2 autorelease];

Anonymous   
Printed Page 357
in the -dealloc method

The last line of the -dealloc method returns [super dealloc], however the method
definition states that it should not return any value. Thus, the word "return" should
be deleted.

Anonymous   
Printed Page 357
The header definition is incorrect in

- (id)init
{
NSString *header = @"{\rtf1\mac{\fontbl\f0\fswiss
Helvetica;}\f0\fs24";

[super init];
data = [NSMutableData dataWithData:[header
dataUsingEncoding:NSASCIIStringEncoding] ];
[data retain];
return self;
}

replace header definition with

NSString *header = @"{\rtf1\mac{\fontbl\f0\fswiss}\f0\fs24 ";

Anonymous   
Printed Page 358
Implementation of RTF class

- (void)setSize:(float)aSize
{
[self appendRTF:[NSString stringWithFormat:@"\fs%d",(int)aSize*2]];
}

should read:

- (void)setSize:(float)aSize
{
[self appendRTF:[NSString stringWithFormat:@"\fs%d ",(int)aSize*2]];
}

The first (string) argument requires a trailing space, after "%d". This
ensures proper parsing of the RTF data for some floating point numbers.

For example, the result of entering "sin pi" is "1.22465e-16", and without
the space, RTF like "fs201 cf0 .22465e-16" is emitted.

I have no idea why this is so, it's easier simply to try it.

Anonymous   
Printed Page 358
middle of page

I can't think of any good reason why the parameter to setSize: should be a float. We
immediately cast it to an integer anyway. Maybe it's because it makes exercise 2 at
the end of the chapter more interesting? At the very least, this needs an
explanation.

Anonymous   
Printed Page 360
Step 8. appendRTFData: declaration

The method appendRTFData: is declared with a NSData *
parameter called "str", yet in the implementation the
actual parameter is "data" .

Thus, the code should read:

- (void)appendRTFData: (NSData *) data ;

Anonymous   
Printed Page 361
step 10

The method replaced by performing step 10 on page 361 is inconsistent with the
original code on page 340. The original method contained a [str release] mesage at
its conclusion, not the [str autorelease] shown on page 361. However, the [str
autorelease] version of the code seems to be intended by the authors, as that same
message was mentioned on page 341 in the sentence beginning, "The third statement
sends...", even though it did not agree with the method listed on page 340.

Anonymous   
Printed Page 366
Third paragraph

Saving the current location and size of the MathPaper window, as in the example, is a
perfectly valid demonstration, of course. However, it would also be helpful to
mention that this is handled automatically by NSWindow when you implement the methods
setFrameUsingName: and setFrameAutosaveName:.

Anonymous   
Printed Page 368
Step 3

The second line of the code example should read
- (id)init
instead of
- (init)

Anonymous   
Printed Page 368
Step 3.

The use of TRUE in [rtf setBold:TRUE]; is logically correct, but inconsistent with
the use of YES and NO elsewhere; for example on p. 361: [rtf setBold:NO];

Anonymous   
Printed Page 368
step 4

All three #import statements should not have a semicolon at the end, and the file
names should be surrounded with double quotes.

#import "PaperController.h"
#import "RTF.h"
#import "MathDocument.h"

Anonymous   
Printed Page 369
Step 4

The code added to windowDidLoad is intended (1) to display the data from the saved
document and (2) to position the window in its previous location on the screen. The
second part does not work. The window frame is set, but this appears to have no
effect -- Cocoa simply cascades the window below and to the right of existing
windows.

I believe an additional line is needed to disable the default behavior:

if ([doc hasFrame])
{
[self setShouldCascadeWindows:NO]; // add this line
[[self window] setFrame:[doc frame] display:YES];
}

Anonymous   
Printed Page 374
Thir paragraph from the end

The line
NSData *theData = |NSArchiver archiveDataWithRootObject:anObject]
is misspelled. It must read
NSData *theData = |NSArchiver archivedDataWithRootObject:anObject]

Anonymous   
Printed Page 383
Step 2.

The initWithCoder: method returns self and should be typed with (id) like this: -
(id)initWithCoder:(NSCoder *)coder

Anonymous   
Printed Page 387
4th full paragraph

With the current Project Builder, the default File->Print command sends
printDocument:, not print: to the first responder object. The NSTextView doesn't
respond to print: so nothing happens when you select Print. You can either change the
action of the Print item to print: or override printDocument: in MathDocument.m:

- (IBAction) printDocument:(id)sender
{
[[self windowControllers] makeObjectsPerformSelector:@selector(print)];
}

Then you need to add a method to the PaperController object:

- (void) print
{
[theText print:self];
}

Anonymous   
Printed Page 389
Excersie 1

There should be a space after the bold "cat" and command..
It currently reads catcommand .. not quite right..

Anonymous   
Printed Page 396
Steps 13 and 15 (on page 397)

These steps references the nib file "MathPaper.nib" which
does not exist. It should read "MainMenu.nib" I believe.

Anonymous   
Printed Page 396
Step 14

I am using the new April 2002 Dev tool set, and in this
version to change the class for File's Owner, it is located
under the general attributes section of the info panel,
i.e. Command-1 and not Command-5. This may change again
in the production release..

Anonymous   
Printed Page 413
inset note

The sentence should read, "M_PI is the ANSI C-defined constant for pi, which is the
ratio of a circumference of a circle to [twice] its radius." Pi is the ratio of a
circumference of a circle to its diameter.

Anonymous   
Printed Page 414
First paragraph just above Step 6.

The text indicates that the [ self display ] method is called
to cause display to be refreshed. However, the code clearly
indicates that [ self setNeedsDisplay: YES ] is being called
instead.

Anonymous   
Printed Page 415
Code section at bottom of page

Similar to the previous error, the CODE for tick: now
DOES call [ self display ] . However, as pointed out
later in the book (page 426 and 427 to be precise)
[ self display ] should hardly ever be called, and
certainly this is not a case when it should. The code
should remain at the more proper:

[ self setNeedsDisplay: YES ]

logic that was there a page previous..

Anonymous   
Printed Page 422
Second paragraph

The explanation does not take into account the considerable time that
Project Builder spends on indexing the project and its imported frameworks
during the first build.

Anonymous   
Printed Page 428
Step 1 -- Middle of page

"... select them one by one and type Control-X."

I believe Control-X should be Command-X

Anonymous   
Printed Page 429
step #13

Despite having the user try to "add the takePercentage: action method to the BarView
class in the BarView Class inspector", and mentioning that one "cannot select the
rectangular BarView instance in the window to add outlets or actions", BarView is not
listed under the "instances" tab. One can either connect to the "Window" instance
(which will bring up the choice to choose the right action), or, contrary to the
warning, control-drag directly to the BarView instance in the window and then connect
the right action. At least for a beginner, this was a confusing subtlety maybe worth
a tiny screenshot.

Anonymous   
Printed Page 435
step 19

In step 19, the instructions say to drag PolygonView.h from PB to IB. In
parentheses it says that you can also choose Classes -> Create Files for PolygonView.
This is incorrect. In this case you would want to choose Classes -> Read
PolygonView.h since we have updated this file in PB and want the changes to be read
into IB.

Anonymous   
Printed Page 455
Steps 5 & 6 -- Top of page

Steps 5 & 6 describe a multiple selection of files "grammar.y" followed by "rules.l"
from the finder and then dragging them into PB's Resources group. When I followed
these instructions explicitly I later got an error when I tried to compile, in step
8. The error something to the effect that a a file was missing.

The fix is to drag the two files from the finder separately. Refer to page 325,
indented paragraph, first sentence.

"It is important that you add grammar.y before you load rules.l ..."

It might also be helpful to mention that the instructions for building GraphPaper
using the Evaluator are somewhat different than building MathPaper, which also uses
the Evaluator. perhaps the difference is because MathPaper is document-based.

Anonymous   
Printed Page 455
Step 11

Step 11 instructs you to add the compiled Evaluator file to the GraphPaper target by
using Project->Add Files and selecting Evaluator in the build directory. Project
Builder wouldn't let me select Evaluator in this way (Evaluator was greyed out). I
found it easier to add Evaluator as a dependent project of GraphPaper by using the
drag and drop method in the targets pane as described at the top of page 326.

Anonymous   
Printed Page 460
Step 28.

It looks as if the @public ivar char *formula isn't needed. The program
works without it, and it clashes with the internal variable 'formula'
in the sendData method, generating two compiler warnings.

Anonymous   
Printed Page 462
Bottom, under step 30

The line:
- initWithFrame:(NSRect)frame

should probably be:
- (id)initWithFrame:(NSRect)frame

Anonymous   
Printed Page 463
Middle of page

an error in the code, left out a third set of brackets:

evaluator = [[NSTask alloc] init] retain;
[evaluator setLaunchPath:path];

should be:

evaluator = [[[NSTask alloc] init] retain];
[evaluator setLaunchPath:path];

Anonymous   
Printed Page 469
code

sendData works when called normally without an argument (i.e., [self sendData];).
However, it cannot be detached as a thread, using Dec. 2002 Developer Tools, unless
it is declared as - (void)sendData:(id)arg. arg does not have to be used in sendData,
but the program does not work as printed--an exception is immediately raised that
there is no autorelease pool. Adding an argument to the declaration of sendData
immediately fixes the problem.

Anonymous   
Printed Page 474
Step 44.

I believe that the line [super init]; is unnecessary, as the NSObject init does
nothing, it only returns self. Removing it does not break the program.

Anonymous   
Printed Page 479
Step 10 -- Lower third

Step 10 omits an ";"

- (void)dealloc
{
[dict release]
[text release];
[super dealloc];
}

should be:

- (void)dealloc
{
[dict release];
[text release];
[super dealloc];
}

Anonymous   
Printed Page 483

Add the following exercise:

6. GraphPaper recognizes 'pi' as the ratio of a circle's circumference to
its diameter. Mathematicians prefer to use the Greek symbol '<' (option-p on
the keyboard). Improve GraphPaper to recognize '<'.

The easy way is to modify -sendData to parse the string 'formula',
substituting 'pi' for '<'. The cleaner and more extensible way is to modify
Evaluator to recognize '<'. -sendData will still need a slight change.

Anonymous   
Printed Page 488
2nd paragraph

"If a user clicks the border of an NSColorWell, the Colors panel is displayed."

You can click anywhere in an NSColorWell and get the same behavior.

Anonymous   
Printed Page 493
Step 22

"Instantiate the Controller class"

should be

"Instantiate the PrefController class"

Anonymous   
Printed Page 493
Step 24, 4th sentence

"... and three Message Text icons from the Cocoa-Views palette and drop them all in
the new panel."

"Message Text" should be "System Font Text".

Anonymous   
Printed Page 523
thru p526

I have been building this project somewhat differently than the book describes. I
have been saving the generated curve directly into a Bezier curve. Then rather than
scale the view down to the bounds of the graph I scale the Bezier curve up to the
coordinates of the view and draw with a 1 pixel pen.

Done this way the lines do not require scaling to draw them. A 1 pixel line is stil
one pixel no matter how the image is scaled and is symmetric.

Further, as the image is in screen coordinates rather than Bezier curve coordinates
the print to PDF problems described on p 523 do not occur. The image prints properly
to a pdf without the need of a temporary window p525, section 6.

Anonymous   
Printed Page 533
setFormat code

In the message implementation for setFormat in Controller,
the first line "savePanel = [NSSavePanel savePanel];" should be eliminated,
and in fact has been in the downloadable code. If you use the code as printed in the
book, it changes the format on a newly created panel, not the one attached to the
window, and thus you can only ever create PDF files.

Anonymous   
Printed Page 544
Step 4

Step 4 imports the ZoomScrollView.h header file into Controller.m, but this code is
superfluous. The clear method called in the next step is declared in the GraphView.h
header file which has already been imported into Controller.m.

Anonymous   
Printed Page 559
between Step 35 and 36

The authors forget to mention that you have to replace the old GraphPaper application
previously placed in the /Applications folder with the newly built GraphPaper
application in order to get the Graph Formula service to work.

Anonymous   
Printed Page 567
next-to-last line

Here the return value from tagAtPoint is compared to -1 meaning "no match found" but
on page 566 in step 14 the code uses 0 for that purpose.

Anonymous   
Printed Page 567
last line

There is no setObjectsToColor:forTag: method. This should be setObjectToColor:forTag.

Anonymous   
Printed Page 584
Step 11

awakeFromNib is erroneously described as a class method. It is not a class method
(+), just a method.

Anonymous   
Printed Page 590
Step 13

"Change some colors and click the Revert button; notice how the original colors
return to the Preferences panel."

I have followed the instructions in the chapter, however my Revert button doesn't
revert the color wells to their original colors. I downloaded and built the
corresponding example program from your ftp site, but it does not appear to work
either.

Anonymous   
Printed Page 602
paragraph cocoa-dev

URL is incorrect should read http://lists.apple.com/mailman/listinfo/cocoa-dev

Anonymous