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.
Version |
Location |
Description |
Submitted by |
Date submitted |
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: @" |