You are currently viewing page 1 in Cocoa: What Is It?

Standard introduction stuff: history, tools, frameworks, how to read the book, typographical conventions, preachy discussion of learning.

Below are errata in the same chapter as page 1.
- "the the" should be just "the"
(page 7; 6 pages ahead)

Below are comments in the same chapter as page 1.
Add a Comment of Your Own- Matt J said the following on Jun 21, 2008:
(comment made on this page)
The change from nib to xib is a change from a binary format to an XML format. Oddly, Aaron explains this later in the book, but obviously, there wasn't enough time to change all the references to nibs to xibs. You'll note that when building, Xcode compiles your xibs to nibs. There's no way Apple would or could get rid of the NeXT references. Almost all classes begin with NS! - John Beatty said the following on Jun 26, 2008:
(comment made on this page)
The last paragraph on this page feels out of place - I think it belongs near the bottom of page 3, as the *last* paragraph of "A Little History," just before the "Tools" section. - Adam said the following on Aug 2, 2008:
(comment made on this page)
In the chapter, "Living with Retain Counts" it doesn't seem like the dealloc method ever gets called. I copied the code as instructed, but when I compile and run the output just shows the lottery numbers and not the "decallocating..." messages in the console. Does anyone have a suggestion? - Adam said the following on Aug 2, 2008:
(comment made on this page)
I found my error. I had set array to nil and then tried to release it:
// Done with 'array'
array = nil;
[array release];
Of course, it should be the other way around:
// Done with 'array'
[array release];
array = nil;
- Barbara said the following on Aug 3, 2008:
(comment made on this page)
Here's a hint for the Chapter 8 question on this page:
You need to fill out the SortKey and Selector fields.
Aaron's hint is that strings have a length method. Combine this with the fact that personName is a string - when you figure out the keypath, but it in the SortKey textfield. Remember - this is one place we do use dot-notation.
As for the Selector field ... The sort key is now a number, not a string, so you don't want caseInsensitiveCompare: as the selector anymore. Look up NSNumber in the documentation and check out its instance variables to find a more appropriate selector. Don't forget that the colon is part of the selector name. - Barbara said the following on Aug 3, 2008:
(comment made on this page)
Apologies -- the "but" should be a "put" ... and I meant look up the instance *methods* for NSNumber. - Tom D. said the following on Aug 11, 2008:
(comment made on this page)
I am compiling on Xcode3.1 and when I run the Chp. 10 RaiseMan code I am able to save a file but when I try and open a file it is grayed out in the finder window. Has anyone encountered this problem?
Thanks in advance,
Tom - Mitch Allen said the following on Aug 15, 2008:
(comment made on this page)
Figure 2.14 shows a view of a .nib, which in the latest Xcode is generated as a .xib. I can't get to that kind of view with the xib to drag an Object from the Library on to it. - Scot Gardner said the following on Aug 28, 2008:
(comment made on this page)
My Book just arrived, its printed with the cover upside down and backwards? anyone else get one like this?
- Jim Schimpf said the following on Aug 30, 2008:
(comment made on this page)
Just got the book and am working through it. In chapter 3 the lottery example when you create the NSCalendarDate item with alloc init, the date is set to Jan 1 2000 and the lottery dates go according to that. I didn't see where that actual time was set (to match the console output). I then changed that to now = [NSCalendarDate calendarDate] and got current date. But later in Chapter 4 when I did [now release]; now = nil I learned about auto release objects.... - Vincent said the following on Sep 7, 2008:
(comment made on this page)
Excellent book, bit of a steep hill so not really for complete beginners, but it's very handy for those like me who started again after being out of programming since the days of the Amiga and Apple-II. :)
One problem I've run into involves the super-easy Carlot programm. After trying to enter a price, it keeps telling me there's a formatting problem, but I double-checked my steps and see nothing wrong with it. Any ideas? - colin anson said the following on Sep 13, 2008:
(comment made on this page)
i absolutely loved reading through this as i have always loved cocoa since i was very young ;) - Johan said the following on Sep 18, 2008:
(comment made on this page)
Noob question here. Noob to X-Code, Noob to Mac, Noob to OS-X. I just worked through the first chapter and the app comes up fine. I ran into the NIB/XIB but solved that. But, I compile the app, it runs and works fine but when I click the red x it disapears from the screen but the app does not shut down. It stays on the Dock. And it's running since when I do another build and go, XCode tells me to stop it first. However, the window is nowhere to be seen. Help? - Chris Baker said the following on Sep 23, 2008:
(comment made on this page)
When creating a new NSObject, it creates the implementation file without a superclass defined. I'm not sure the right way to get it to define the object name and superclass name both from the interface builder. - Shawn said the following on Sep 24, 2008:
(comment made on this page)
Where can we download the solution examples bignerdranch.com's link for this doesn't work. - John said the following on Sep 26, 2008:
(comment made on this page)
I'm having the same problem as described by Mohan in June or July of 2008: the OpenGL project in Chap 33 gives me just a solid green window. Using NSLog statements I'm observing drawRect being called, and displayList being assigned the value 1. Any debug techniques would be greatly appreciated - Paul Johnson said the following on Oct 12, 2008:
(comment made on this page)
.nib files have an .xib variant, and when I create a project on my own system I don't even see a .nib file. I have a .xib file instead. There should be some discussion of this near the first reference to a .nib file. - dave said the following on Oct 14, 2008:
(comment made on this page)
The Raiseman application (chapter 8) is running but without any display output (no window). Obviously, the 3.1 environment is different than the book (MyDocument.m specifically) so I changed to emulate your code exactly. Regardless, I can't seem to get any output. I've rechecked this code/IB several times all is ok and no errors/warnings. - Paul Johnson said the following on Oct 16, 2008:
(comment made on this page)
For Dave: I just completed Chapter 8, except for the Challenges which I'm still working on. The RaiseMan program runs just fine for me. You might try downloading the completed project from the bignerdranch website and compare it with what you've got. I did have some difficulty setting things up correctly in IB, and I'm a little fuzzy on why I needed to do certain things; I'm hoping all this will be clarified as I progress through the book. - Paul Johnson said the following on Oct 17, 2008:
(comment made on this page)
Aleksey, you want "setObjectValue" instead of "SetObjectValue". - Stephan Huebner said the following on Oct 18, 2008:
(comment made on this page)
In the Lottery-app, Just for the sake of it, I wanted to try to release the "result"-NSString before returning it (in the description-method), which is stated as being false and would not work at all. So the code looks like this:
NSString *result;
result = [[NSString alloc] initWithFormat:@"%@ = %d and %d",
[entryDate descriptionWithCalendarFormat:@"%b %d %Y"],
firstNumber, secondNumber];
[result release];
return result;
In the book it is stated that this would not work at all. However, the app runs just fine, printing all like it should. Am I missing something? - Stephan Huebner said the following on Oct 18, 2008:
(comment made on this page)
Very strange. About the above mentioned problem. If I insert breakpoints before releasing "result" and after, I see that "result" gets invalid. So it seems to "work" like the book describes. But if I take out the breakpoints, the app just runs fine again. - Paul Johnson said the following on Oct 18, 2008:
(comment made on this page)
Stephan, although you've released the memory and thus made it available for use elsewhere, no other use has been made of it yet. The pointer still references this memory but everything still works because nothing else has overwritten memory yet. Releasing doesn't clear the pointer. - Paul Johnson said the following on Oct 19, 2008:
(comment made on this page)
The version of RaiseMan for Chapter 10, downloaded from bignerdranch.com produces the following error when run on Mac OS X 10.5.5:
2008-10-19 17:16:40.752 RaiseMan[7994:10b] -[NSDocumentController fileExtensionsFromType:] is deprecated, and does not work when passed a uniform type identifier (UTI). If the application didn't invoke it directly then the problem is probably that some other NSDocument or NSDocumentController method is getting confused by a UTI that's not actually declared anywhere. Maybe it should be declared in the UTExportedTypeDeclarations section of this app's Info.plist but is not. The alleged UTI in question is "com.bignerdranch.raiseman-doc".
- Stephan Huebner said the following on Oct 20, 2008:
(comment made on this page)
@Paul Johnson
Thanks for the explanation. I just forgot that this command does not actually "clear" the point, as if one would clear a usual variable but that it only realeases the reference. That was what confused and bothered me. - Ken Getz said the following on Oct 23, 2008:
(comment made on this page)
Overall, I really like this book. The examples are just the right level of difficulty for me, and I'm learning a lot as I work through every single example, typing in everything myself.
One thing that would IMMENSELY improve the quality of the book, for me:
When I write technical training materials (and I've written thousands and thousands of pages of books, articles, and courseware), I never use a any method, property, variable, and so on, until I've defined it. That is, the code compiles after EVERY step. There are too many places in the book where you add code that won't compile. I use the compiler to help me determine that I've typed the code correctly, and this makes it frustrating and impossible to do that.
For example, in Chapter 14 (using notifications, where I currently am working), in the Registering an Observer section, you use a selector named handleColorChange: before you define it. Why not define it first? And then add the observer? As it was, I took the time to try and find if there was some built-in selector named handleColorChange:, then turned the page to find the definition there.
Really, this would make a huge improvement in the book, overall. Someone needs to just work through every example, and if the code doesn't compile, re-order the introduction of class members so that it does. Thanks -- Ken - Markus said the following on Oct 26, 2008:
(comment made on this page)
I love the book, my issue is with the Core Data parts which are pretty small. All example uses tables. I tried to unsuccessfully use an popup to select a given record and display the atributes of the popup selected record in text fields. Sounds easy, but there is no info on the book or anywhere else on the net which tells me how to do this.
Help ... . - Paul Johnson said the following on Oct 27, 2008:
(comment made on this page)
for Ron Green:
I don't think you need to touch stopIt. stopButton and startButton get toggled properly in speechSynthesizer:didFinishSpeaking: - Paul Johnson said the following on Oct 27, 2008:
(comment made on this page)
Chapter 13 challenge. I put the following method in PreferenceController.m. This seems to do the trick. (You need to make the button, etc. in IB, of course.) I added the synchronize call when I observed that the resetting did not occur if the program was terminated soon after resetting the preferences. I also called WindowDidLoad to avoid code duplication, but I question whether or not this is good coding practice. (Comments?)
- (IBAction)resetPreferences:(id)sender {
// Get shared defaults
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// Remove program defaults
[defaults removeObjectForKey:BNREmptyDocKey];
[defaults removeObjectForKey:BNRTableBgColorKey];
[defaults synchronize];
// Update preference panel
[self windowDidLoad];
NSLog(@"Reset to defaults: Checkbox = %d; Color = %@", [checkbox state], [colorWell color]);
}
- Paul Johnson said the following on Oct 27, 2008:
(comment made on this page)
If anyone can tell me how to post code to this forum without losing formatting, I would appreciate it. - Paul Johnson said the following on Oct 27, 2008:
(comment made on this page)
The solutions file available for download from bignerdranch.com has an error in the Chapter 14 folder. In PreferenceController.m the definitions for the string constants should be typed "const":
NSString *const BNRTableBgColorKey = @"TableBackgroundColor";
NSString *const BNREmptyDocKey = @"EmptyDocumentFlag";
NSString *const BNRColorChangedNotification = @"BNRColorChanged";
- Paul Johnson said the following on Oct 30, 2008:
(comment made on this page)
In the Chapter 18 solutions folder (downloaded from bignerdranch.com) there is a minor error in the App Controller object in MainMenu.nib. There is a warning about an unused outlet named "slider". In IB the outlet should be deleted from App Controller. - Wayne Sadecki said the following on Nov 6, 2008:
(comment made on this page)
For the Chapter 15 'Challenge', I did the following to my code. It works, but there is no solution in the downloaded solutions for the challenge. Just wondering if there is a more elegant solution.
A. Added the otherButton to the NSAlert
NSAlert *alert = [NSAlert alertWithMessageText:@"Delete?"
defaultButton:@"Delete"
alternateButton:@"Cancel"
otherButton:@"Keep, but no raise"
informativeTextWithFormat:@"Do you really want to delete %d people?", [selectedPeople count]];
B. Added the following if check and for loop to alertEnded
if (choice == NSAlertOtherReturn){
NSArray *selectedPeople = [employeeController selectedObjects];
for(Person *selPerson in selectedPeople){
[selPerson setValue:[NSNumber numberWithDouble:0.0] forKey:@"expectedRaise"];
}
}
- Wayne Sadecki said the following on Nov 6, 2008:
(comment made on this page)
In chapter 3 of the Cocoa Programming for OS X, third edition I see there is a use of NSCalendarDate. I found the following note in the help documentation for NSCalendarDate.
Important: Use of NSCalendarDate strongly discouraged. It is not deprecated yet, however it may be in the next major OS release after Mac OS X v10.5. For calendrical calculations, you should use suitable combinations of NSCalendar, NSDate, and NSDateComponents, as described in Calendars inDates and Times Programming Topics for Cocoa.
- Wayne Sadecki said the following on Nov 6, 2008:
(comment made on this page)
In the third edition the section titled "What Have You Done?" for Chapters 3 and 4 are exactly the same. Looks like a cut and paste error from the editor.
The following objective C test returns YES, where the isEqual implementation compares the text of NSString objects of the sections.
[chapter3 whatHaveYouDone] isEqual:[chapter4 whatHaveYouDone]
- Wayne Sadecki said the following on Nov 10, 2008:
(comment made on this page)
Chapter 17 Challenge:
In the downloaded solutions, there was no solution to the challenge question. I replaced the 'lineToPoint' line of code with the following. I also changed to the code back to drawing the line rather than filling the space.
[path curveToPoint:p controlPoint1:[self randomPoint] controlPoint2:[self randomPoint]];
This seems to do what is requested of the challenge question, but I really don't know for sure if there is a better way to accomplish the challenge question.
- Wayne Sadecki said the following on Nov 10, 2008:
(comment made on this page)
Two comments on the RaiseMan example in Chapter 9 regarding the NSUndoManager.
In the example, the book is using the 'Person *p' pointer after doing a '[p release]'. I'm not sure if that is absolutely wrong in this example, but I don't think it is a best practice to use a pointer after you've done the release.
Also, in the following code, I think you should find the column number of the personName column, rather than hard coding the column 0. Of course, you will need to go into interface builder first to create the column identifier for the personName column.
The code in the book can be changed from:
[tableView
editColumn:0
row:row
withEvent:nil
select:YES]
to:
[tableView
editColumn:[tableView columnWithIdentifier:@"personName"]
row:row
withEvent:nil
select:YES]
- Wayne Sadecki said the following on Nov 10, 2008:
(comment made on this page)
In Chapter 10, in the first section descibing the coding and decoding, should the book explain that the order of instance variables being coded and encoded should be in a consistent order (Or doesn't that matter of Objective C)?
- Johan said the following on Nov 10, 2008:
(comment made on this page)
WAYNE: regarding your solution to CH15. I did the same thing BUT my for loop looks like this:
for(Person *p in selectedPeople)
{
[p setExpectedRaise:0.0];
}
Figured that since the Array holds only pointers to object I can manipulate the objects using their accessor methods.
Don't know if this is good/bad but there you go. - Wayne Sadecki said the following on Nov 11, 2008:
(comment made on this page)
JOHAN: Thanks for your solution to Ch. 15 Challenge.
Chapter 18, Figure 18.6 looks to be incorrect. I see a 'slider' as an Outlet for the AppController, but the slider is not defined as an outlet by the AppController class (p. 252). - Martyn said the following on Nov 11, 2008:
(comment made on this page)
I've searched everywhere and can not find the reason or explanation as to why the asterisk is inside the bracket, e.g.
- (void)setEntryDate:(NSCalendarDate *)date;
any help, however small, would be greatly appreciated - Johan said the following on Nov 11, 2008:
(comment made on this page)
MARTYN:
Not sure exactly what you're asking so if I'm off track and pitching this way too low level for you, forgive me.
Basically it means that 'date' is a pointer to an NSCalendarDate object. Since this is a parameter being fed to the method, 'setEntryDate:', it means that the method can use the pointer to access the 'date' object's instance variables and methods.
Assume you have a C prog and it declared aNum like this
int aNum;
aNum = 5;
//And if you have a function
(int)doSomething(int x){
return x +2;
}
//and later in the prog you call the function like so:
result = doSomething(aNum);
doSomething() will know that it is getting an int. It MAKES A COPY of it and assigns it to 'x', known only to itself. The answer it returns goes into 'result' BUT 'aNum' is still 5, 'result' will be 7
Let's rewrite it to use pointers
int aNum = 5;
int * numPtr;//an empty pointer that can point to an int
numPtr = &aNum; //so we've set up the pointer to point to
//aNum, very similar to the (NSCalendardate * date)
(void)doSomething(int * x){
// Note the * in the parameter, it
//means doSomething() is expecting an int pointer
//x and numPtr is the same thing and both access aNum
return (*x +2);
//It's important to realise you did NOT make a copy of 'aNum'
}
//and you call it like so
doSomething(numPtr);
if you now look at aNum, it's value will be 7 (i.e. 5+2) - Johan said the following on Nov 11, 2008:
(comment made on this page)
Oops! Sorry Martin. I made some typos. Too much of as hurry!
in the second doSomething function there is no return, you simply state
*x = (*x)+2;
In English, put back into the integer pointed to by x the value of the integer pointed to by x plus 2
Also, I said (NSCalendarDate * date), which should be (NSCalendarDate *) date
By the by, that would be considered a cast in C. I.e. You are casting whatever 'date' is to be seen as whatever type is given between the brackets.
- Martyn said the following on Nov 12, 2008:
(comment made on this page)
Johan,
Thanks for the reply. The explanation and examples have done the job.
Many thanks. - Stephen Watson said the following on Nov 13, 2008:
(comment made on this page)
I'm doing the 2nd challenge in Chapter 6 and I'm stuck. I've downloaded the solutions but I'd like to try and complete it with just a little help before I peek ...
In my AppController class I've added:
NSMutableArray *toDoList;
in the AppController's init method I've written:
toDoList = [NSMutableArray array];
and according to the debugger it looks OK.
When the user clicks the Add button I run the following method:
- (IBAction) addNewItem:(id)sender
{
NSString *string;
int len;
string = [textField stringValue];
len = [string length];
if ( len > 0 )
[toDoList addObject:string];
NSLog(@"Add clicked - String is %@", string);
}
But when the code runs the statement [toDoList addObject:string]; I see the following in the debugger:
Program received signal: “EXC_BAD_ACCESS”.
At this point toDoList looks fine, and the contents of 'string' in the debugger shows as the text I typed in the TextField so, please, what am I missing?
Thanks for any help. - Greg Deward said the following on Nov 17, 2008:
(comment made on this page)
I am trying to learn Cocoa and am having difficulty remembering which direction to CTRL-drag controls to wire up the controls. For example, dragging from my button to my App Controller (NSObject) or vice versa. Does anyone have a way to explain this that might make it stick?
It seems to me that a button should make a call to my App Controller when the click event is fired; therefore I should CTRL-drag FROM the button TO the NSObject. This would allow me to select the appropriate Received Action (ie, "doSomething", etc."). However, if I need to do something with a text box (read from it) and a table view (insert an item), I should go the other way... since I'm going to fetch from the text field and then insert into the NSArray that is feeding the text view. - Michael Coddington said the following on Nov 25, 2008:
(comment made on this page)
Re: The RaiseMan example in Chapter 8. I also had a problem (with XCode 3.1.1) not displaying the window I had set up in IB for MyDocument.xib. After taking a look at the completed project downloaded from this site, I realized I made a mistake that might trip up other noobs like myself.
When I first created MyDocument.m/h some boilerplate code was created inside MyDocument.m. And when I got to the part in the book where it specified what to add to that file, I wiped out the boilerplate stuff (windowNibName, windowControllerDidLoadNib, etc.) and just typed in what the book specified.
Oops! I broke the app; no window appeared. After adding the boilerplate code back in, voila, everything was OK.
It might be useful to caution people not to remove that auto-generated code if doing so will have an adverse effect... - Steve said the following on Nov 28, 2008:
(comment made on this page)
Why add code to CarLot?
to get the date set to todays date simply put now in the default value of the datePurchased attribute. It works just fine. I am still on my first week of learning Cocoa and I am so proud that I was able to think of this!!!
If there are any problems that could arise from this someone please let me know. - Stephen said the following on Dec 3, 2008:
(comment made on this page)
Hi Freerider,
I had:
NSTextField *summary
... in my class and then called the following in my implementation:
[summary setStringValue: [NSString stringWithFormat:@"'%@' contains %d character%c", [textField stringValue], numChars, numChars == 1 ? ' ' : 's']];
The + in the method description means that the method is applied to a class object, not to an instance.
Does that help? - Stephen said the following on Dec 3, 2008:
(comment made on this page)
Freerider:
Looking again I think your problem is not the class method but that you're passing the NSTextField in for formatting whereas you need to call the method stringValue as I've done to actually extract the text component of the object. - Avery said the following on Dec 5, 2008:
(comment made on this page)
In the Count Characters challenge, I was able to do it, except my output NSTextfield (which is a Label) clips the characters. If I manually make the Label as large as possible in IB, then it works fine, but is there a way to programatically set the size of a control (so it doesn't clip the glyphs) and set the location in the center of my window? - FreeMan said the following on Dec 13, 2008:
(comment made on this page)
Page 127.
Xcode create a template for several methods that do not appear in this page.
Page 128:
"the column's cell" should be "the text field's cell"
Page 195:
The challenge section proposes to create an About panel. However currently Xcode also creates a default About panel.
Page 210:
"A notification center allows objects in an application to send notifications to other objects in the same application. Notification do not travel between applications".
These sentences must be removed because there exist distributed notification centers.
Page: 310:
Figure 24.3 is inexact. In the source code there is not an outlet from AppController to NSProgressIndicator but a binding from NSProgressIndicator to the "count" property.
Page 393:
The blaster button must be associated with the blastem: method.
Page 394:
The autosizing of the view and buttons must be set in Interface Builder.
- Vojko Voga said the following on Dec 14, 2008:
(comment made on this page)
I am in chapter 6 an I have a question.
In book he says: "Also, set the AppController to be the delegate of the table view."
And I am wonder why I have to create this in Interface builder but we set delegate like for speechSynth object in init function - [speechSynth setDelegate:self];.
So I try to set delegate like:
[tableView setDelegate:self];
It compiled ok but it didn't work.
Isn't this the same thing? - Ephraim said the following on Dec 18, 2008:
(comment made on this page)
I'm trying to do the Lottery example on page 46.
The new file dialog shown in the book shows the file as part of the Lottery project. However, no directions for creating that project are given.
The 'New Project' menu item gives dozens of choices for a new project type. What type is the undescribed Lottery project? - Vojko Voga said the following on Dec 19, 2008:
(comment made on this page)
Ephraim .... this is Foundation Tool. You can see that on page 35 last paragraph.
- Thomas Holl said the following on Dec 23, 2008:
(comment made on this page)
To Stephen Watson,
I did encounter such situations sometimes. I am not an expert but I can help you I think (I am beginning the chapter 8).
You instanciated your NSMutableArray *toDoList in the init method this way :
toDoList = [NSMutableArray array];
try this instead :
toDoList = [[NSMutableArray array] retain];
or
toDoList = [[NSMutableArray alloc] init];
I tried your method and it did not work, the 2 others did.
Actually I would like to well understand when objects are allocated/initialized and when references are lost.
alloc, new, copy, mutableCopy lead to a retain count=1. References got by other way have a retain count = 1 and are in the autorelease pool (wrote page 73).
I would like to know when your toDoList (which is a reference to an instance created with [NSMutableArray array] is lost. I still need to have a deeper understanding of the alloc/dealloc process with their scopes (when and where), for now I can't help you about that.
Something else:
-you will need to tell the tableView to reload data after you have updated the mutableArray ([myTableView reloadData];)
-The test of the non 0 length is fine but one can add a test to be sure that the string is not only made of spaces. I could add many lines which were invisible before I add this test.
Hope this helps,
- Justin said the following on Dec 26, 2008:
(comment made on this page)
I cannot figure out why the RaiseMan application will not show the MyDocument window when I launch it. I followed the book, but I don't know enough to figure out the problem. Can anyone help? - Jim Plamondon said the following on Jan 2, 2009:
(comment made on this page)
Overall, great book, in overall plan, flow from chapter to chapter, and in most details.
Here's a minor nit which, if picked, might save others from a bit of frustration.
On p132, the book states "...in the Attributes inspector, set the keyboard equivalent to the Delete key (Figure 8.12)." It took me quite a while to discover that I needed to (a) click in the blank area between the "Key Equiv." label and the "Clear" button, and then (b) press the Delete key. - Jim Plamondon said the following on Jan 2, 2009:
(comment made on this page)
I'm having a lot of trouble with key-value coding. I think I understand the basic idea, but the examples that I've encountered so far (p143 of this book discussed on this page, and some of Apple's documentation) seem both contrived and dangerous. I must be missing something.
For example, consider one of the examples provided in Apple's documentation: "Using Key-Value Coding to Simplify Your Code" (developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/Overview.html#//apple_ref/doc/uid/20001838-SW1). The example is introduced a follows:
"You can use key-value coding methods in your own code to generalize implementations. For example, NSTableView and NSOutlineView objects both associate an identifier string with each of their columns. By making this identifier the same as the key for the property you wish to display, you can significantly simplify your code."
And, of course, this WILL simplify your code -- but it also makes the code's localization nearly impossible. The column's localized name won't match the names of the corresponding instance variables in your "simplified and generalized" code. To localize the app to Italian (or whatever), you'd have to re-write the "simplified and generalized" code to use the Italian column names for its relevant instance variables. What am I missing here?
Perhaps this will all become clear to me later, but it sure ain't clear so far. - Jim Plamondon said the following on Jan 3, 2009:
(comment made on this page)
This is not a complaint. Rather, it is a description of my own confusion when studying a specific section of the book.
By the end of implementing the sequence of Interface Builder actions described on pages 128-132, I was actually laughing out loud, thinking "sure, why not, let's just go ahead and connect all this stuff together and see what happens" sort of way. "Maybe it will all be explained later." Performing a ritual incantation, if you will. Then the chapter suddenly ended.
When I got to page 144, and encountered the sentence "Because we have bound the contentArray of the array controller to the employees array of the MyDocument object,..." I said to myself, "I didn't do any such thing!" I had to walk backwards through the book to find the instruction to make the relevant connection (halfway down p128).
Up until page 128, the book had done a very good job of providing a rationale for the various IB connections. For example, the discussion of "target-action" connections provided a simple and useful rationale. Then, in the description of a set of connections that was both complicated and novel (starting on p128), no such rationale was provided.
For example, I was surprised to be typing, into IB's Array Controller Attributes' window's Key list, the names of Person's instance variables (personName and expectedRaise). Having already set the Array Controller's Class Name field to "Person," shouldn't IB *know* (I wondered) what Person's instance variables were, such that I could select them from a pop-up or somesuch? Perhaps my having to type them in meant that I had done something wrong -- e.g., made a connection improperly (like in XCode's text editor, when you misspell a class name and so it fails to change color; the failure to change color indicates that something is wrong).
The next instruction was even more inscrutable. "In the Bindings Inspector, set the value to display the personName of the arrangedObjects of the NSArrayController, as shown in Figure 8.8 (page 130)."
"arrangedObjects"? Where the heck did that come from? I didn't recall ever having heard of "arrangedObjects" before, or of learning any rule which would have made it clear that "arrangedObjects" was the right choice for such a binding. Had I accidentally skipped the portion of the book in which such a rule was explained? I looked up "arrangedObjects" in NSArrayController's documentation, but was not enlightened as to why this property was the appropriate target for such a binding (as opposed to, say, "the receiver’s content collection," whatever that was; NSArrayController's documentation used the phrases "content collection" and "arranged objects" without ever defining them or clearly distinguishing between them). What the heck was going on here?
At least the "Model Key Path" control allowed me to select "personName" from a pop-up, which suggested that at least I was doing this mysterious thing properly (but then, why wasn't I provided with a similar pop-up earlier? Had I screwed that up?)
Then the book instructed me to "reselect the second column. In the Bindings Inspector, set value to display the expectedRaise of the arrangedObjects of the NSArrayController, as shown in Figure 8.10." Looking at Figure 8.10 it was clear that the first (left-hand) column was selected, just as it was in Figure 8.8. The text and figure disagreed. More confusion.
And so on.
Obviously, describing my confusion this openly makes me sound pretty dense. And maybe I am. But my superficial density sometimes enables me to find a deeper simplicity that quicker people may miss, so it has its advantages. ;-)
I hope that this train-of-thought (or perhaps, "stagecoach-of-thought") description of my confusion will be of some value should future editions revisit this chapter.
- mkrus said the following on Jan 6, 2009:
(comment made on this page)
I can't get the Chapter 8 RaiseMan to work either. Followed instructions, left all generated code, but get no main window. Console show errors in converting to number.
I removed the formatter and then the main windows comes up fine, but when I click Add Employee, I get an error about inserting a Person object in the array... - vojko said the following on Jan 7, 2009:
(comment made on this page)
I leave generated code and added my own. Add app works fine.
So, what error do you get? - Jim Desposito said the following on Jan 7, 2009:
(comment made on this page)
Chap 8: I could use some additional explanation on the first challenge. I thought I understood what a key path is but I guess I don't since I don't get how it helps in this case. In IB I replaced caseInsensitiveCompare with length and got the result, sort of - it takes two clicks on the top bar to reorder the names list. - Simon said the following on Jan 7, 2009:
(comment made on this page)
Hi !
Chapter 11: At the beginning when you should create table view attributes in IB, I encountered some problems to add a checkbox in the 3d column.
Indeed, I could not delete the label "Text Cell" to add a checkbox, like it is explained in the book. I saw the MyDocument.nib solution, and it is possible !!
Have you any ideas ? Why I can not to do this ?
Thx - Simon said the following on Jan 9, 2009:
(comment made on this page)
Hello, I'm sorry, problem resolved, I choosed a checkbox in NSButton wheras it is a NSButtonCell checkbox cell that we must must choose in a Table View. That is the problem when you read fast !
- John W said the following on Jan 9, 2009:
(comment made on this page)
I'm working through Chapter 12, trying to add the preferences panel. I've double checked everything, but it doesn't appear.
showPreferencePanel is definitely called, and there are no errors reported.
Any ideas?
- Dav said the following on Jan 16, 2009:
(comment made on this page)
Chapter 8: I got stuck on the first challenge mainly because KVC and key paths access things in an indirect manner. I think I needed more help than the book provided on these topics.
Barbara's comment on this page Aug 3, 2008 points to the solution.
Like Jim Desposito I first tried replacing caseInsensitiveCompare: with length. Doesn't really work.
The answer involves changing attributes for Table Column Name as follows:
Sort Key: key path goes here (p118 explains dot notation by calling accessors but then the book states it won't be used which led me to believe dot notation won't be used to call any methods. The answer involves calling length method here.)
Selector: appropriate method goes here
The answers:
Sort Key old: personName
Sort Key new: personName.length
Selector old: caseInsenstiveCompare:
Selector new: compare:
Sort Key old is a string so you can use caseInsensitiveCompare: however Sort Key new returns the length which is an NSInteger so you need a new Selector the compare: method which can determine the ordering of two NSNumber objects.
- Laurie said the following on Jan 17, 2009:
(comment made on this page)
Excuse me. It's important to begin a search on a full stomach.
I am from Ukraine and now teach English, give true I wrote the following sentence: "Know when to holdem, know when to foldem at the rd annual sarta texas holdem poker tournament and bbq."
Best regards :-D, Laurie. - Jim Desposito said the following on Jan 20, 2009:
(comment made on this page)
Thanks Dav. It's one of those solutions that when you see it you say 'of course'. - Jim Desposito said the following on Jan 27, 2009:
(comment made on this page)
Chapter 26: did anyone else notice that when you add the ColorFormatter class and implement the ability to change the background color the original functionality of TypingTutor is lost?
Did I do something wrong or is this an 'undocumented feature'? - Thierry said the following on Feb 8, 2009:
(page 2; 1 page ahead)
I'm a real beginner un Cocoa programming and unfortunatelly like all beginners I'm stuck at chapter 6 at the NSTableView data source.
The list of voices does appear in the tableView, but the tableViewSelectionDidChange method didn't fire any event.
There is no trace in the NSLog.
I also tried to change the voice in the init with [speechSynth setVoice:@"Agnes"]; but nothing happened ?
Could you help me ?
I cannot see in this example were we define the delegate for tableView.
I can post my code if needed
Thanks in advance
Thierry - ArtSpot said the following on Feb 11, 2009:
(comment made on this page)
Vincent,
I was perplexed by this format issue too. Seems you need to type "$" for the currency formatter to accept the numeric values. I hope there is a work around to this as this seems silly.
Art - David Yamartino said the following on Feb 12, 2009:
(comment made on this page)
Page 49 Question - First paragraph under "Changing lottery.m" states:
Now let's look at lottery.m. Many of the lines have stayed the same, but several have changed.
Question: Did I miss something up to this point - How have they changed? Who changed them?
Or is this paragraph saying: We're about to change lottery.m. You'll notice that we're going to leave many of the lines the same, and change several.
The reason I'm asking this is because I'm having a hard time getting an error-free build (I probably miscopied something) but I'm wondering if I could have missed a step.
Thank for your help. - David Yamartino said the following on Feb 12, 2009:
(comment made on this page)
.
Page 49 Question - Cancel request - I got it to work.
It was a defective unit behind the keyboard. - Gavin said the following on Feb 14, 2009:
(comment made on this page)
I was having problems with Raiseman in chapter 10 (Archiving) I could save files, but when I tried to load a file I got the spinning beachball of doom, ad I would have to force Raiseman to exit. I could not work out what was wrong, I put loads of debug statements in the code and everything looked fine, the setEmployees: method was being called with the correct data from the loaded file. I put nslog statements in every method and the last method to be called was windowControllerDidLoadNib: and everything appeared to be fine. I suspect the was a problem with the interface builder config but I have no idea how to debug where I can't see any code.
Finally I decided to track down the source form the book and try the code from solution download.
When I run the raiseman project from the solutions source, again I can't load the data from a .rsmn file (or any other file) and I get this message:
The document “rmnew4.rsmn” could not be opened. RaiseMan cannot open files of this type.
I've not changed anything and am completely lost.
anyone had similar problems and resolved them? - Gavin said the following on Feb 14, 2009:
(comment made on this page)
Oh yeah, in addition I've noticed that when i save a file with the solutions source there's no default file extension (.rsmn) to save the file as...
hmm.. - Georgi said the following on Feb 15, 2009:
(comment made on this page)
I am having problem with Raiseman in chapter 8 (Challenge 2). I complete everything and the application is working without relying on the NSArrayController. However when a person object is deleted from the table view (through deleteSelectedEmployees: ) the following error is thrown in the log window:
"RaiseMan(26143) malloc: *** error for object 0x3040: Non-aligned pointer being freed (2)
*** set a breakpoint in malloc_error_break to debug"
I put some log entries in order to see what is going on, but so far I am stuck.
What I was able to discover so far is that this happens right after I call the NSMutableArray method removeObjectsAtIndexes: - as from the text in the book ("[employees removeObjectsAtIndexes:rows]"). This is causing the Person object(s) contained at the selected rows to be deallocated (I can see log messages from within the person object dealloc:) and right after this the error is dumped in the log.
I believe that the application is trying to free a memory which already has been freed, but why?
If I comment out the line in createEmployee: method ( [newEmployee release]; ) which releases the retain count of the object it works fine, but then I guess the app will leak memory...?
Anyone hit the same problem? - Georgi said the following on Feb 15, 2009:
(comment made on this page)
Ok - further digging shows that error is thrown right after deallocating the personName NSString in Person.m - (void)dealloc, i.e. after the line "[personName dealloc];"
I have modified the -(id)init of the same class, to initialize the instance of the personName in the following way:
personName = [[NSString alloc] initWithString:@"New person"];
instead:
personName = @"New Person";
although I think these are equal. Still - the same behavior... - Georgi said the following on Feb 15, 2009:
(comment made on this page)
Of course ... the problem was in my code :) As visible and from my previous comment I got
[personName dealloc]
in - (void)dealloc method in Person.m, instead of having the
[personName release]
- which is the correct one.
Cheers & happy coding :) - Quincy Prioleau said the following on Feb 18, 2009:
(comment made on this page)
I am working on Chapter 15 on Making the user Confirm Deletion. I don't know if I am doing something wrong but this is very confusing! The code is as follows:
NSArray *selectedPersons = [employeeController _
selectedObjects];
I understand that the employeeController is the name of my Array Controller object in IB, and my array controller object has employeeController as it's name, but the compiler is not recognizing the name at all. Please help anyone? - Dave Stampf said the following on Feb 23, 2009:
(comment made on this page)
Hi,
I was working on the project in Chapter 8 - the start of the "RaiseMan" app and ran into 2 surprises.
If you do *exactly* as the book says (including the very fine print in the screen shots, things work, but ...)
Problem 1 - if you set up the NSNumberFormat object to be the OSX 10.4 version, truly bizarre things happen. When I pick the style to be "percent" and run the program, all of the new people have their raise set to 500%. OK - I'm probably missing a multiplier somewhere, but that isn't the weird part! Add a few new people, then change the percentage of the last to be something reasonable, say 5%, hit enter and all of the percentages change - for the worse, in my case, to 5,000%. (The one I changed stays at 5%).
Problem 2 - how does one remove a NumberFormat? The little X that appears next to it in the window is non-functional.
In general, this chapter left me clueless as to all of the various options that are available when setting up the NSArrayController. A more gradual approach might have been better.
Otherwise, pretty good book and I enjoy listening to Aaron when he is on the mdn podcasts.
Cheers
Dave
- Paul said the following on Feb 25, 2009:
(comment made on this page)
Hi,
I am a Cocoa/Objective C programming beginner. My background is mostly C++. I am currently reading this book, and I really love it.
I have reached the point of coding the challenge of chapter 18, where a custom view is used to draw oval shapes and save them into a document.
In my solution, I end up having to #import my document class in my custom view implementation, which does not look quite right.
Is there a way to get rid of such a dependency ?
Thanks for your help.
Paul - Mark Barron said the following on Mar 1, 2009:
(comment made on this page)
Hi Dave Stampf
You wrote about the formatting and using 10.4 OS
This made me curious and I was able to play around
to reach this solution:
@implementation Person
- (id)init
{
[super init];
expectedRaise = 4.51;
personName = @"New Person";
return self;
}
Number Formatter Attributes:
Positive Format : #,##0.00
Pos/Neg Suffix : %
To edit percent raise, simply type in
10.32
Mark - Mark Barron said the following on Mar 2, 2009:
(comment made on this page)
MyDocument.h follows:
#import
@class Person;
@interface MyDocument : NSDocument
{
NSMutableArray *employees;
IBOutlet NSTableView *tableView;
}
- (void) setEmployees:(NSMutableArray *) a;
- (void) insertObject:(Person *)p inEmployeesAtIndex:(int)index;
- (void) removeObjectFromEmployeesAtIndex:(int)index;
@end
I am through chapter 10. All is working. I return to p. 135 and decide to try to call
the method there in MyDocument.m , namely:
- (void)tableView:(NSTableView *)tv
sortDescriptorsDidChange:(NSArray *)oldDescriptors
{
NSArray *newDescriptors = [tv sortDescriptors];
[employees sortUsingDescriptors:newDescriptors];
[tableView reloadData];
}
When I click the headers of the running program RaiseMan,
I expect this method to by triggered. It is not. Why?
I did a ctrl-click on File's Owner and then a Drag
from New Referencing Outlet to the TableView in the RaiseMan
window. After that I saw in the Referencing Outlet List delegate
of File's Owner(which is at mid page 128 is "the instance of
MyDocument")
Multiple
x RaiseMan
x TableView(Name, Raise)
Still tableView:sortDescriptorsDidChange does not get
called.
The sorting is being handled by the ArrayController and the
TableView, but still it seems to me, this method should be
invoked. Or?
In the language of Windows, I want the
"sortDescriptorsDidChange" event to call the delegate
function tableView:sortDescriptorsDidChange: inside
the MyDocument object.
Many thanks from a puzzled newbie, Mark - Dave Stampf said the following on Mar 2, 2009:
(comment made on this page)
Hi Mark Barron,
Thanks for your response to my question about NumberFormatters, but I'm still a bit confused - not so much by the format that is displays (although that is odd) but by the behavior when one has multiple lines.
Using the example from the book, if I were to use a 10.4 style number format with the % style selected and the format set to: #,##0%
I run the program and add three new people. The table shows raises of 500% for each. That isn't too unreasonable given the the number in the program is 5 and we really should be dealing in smaller numbers for percent.
The REAL puzzle to me is that when I change the raise of the first person to 15%, the second and third persons raise also changes - in this case to 50,000%.
There is no reason for them to change, yet they do.
Best wishes
Dave
- Mark said the following on Mar 8, 2009:
(comment made on this page)
Hi Dave,
Sounds like the formatter is expecting , say 0.05
for input and you give it 5.00 or 5%, which is 100
times higher. Hope this helps. If I am wrong about
this, I can only suggest selecting, deleting and replacing the formatter. - Mark Barron said the following on Mar 11, 2009:
(comment made on this page)
Chapter 24 Challenge page 316:smooth Scrolling autoscrolling mouse
------------------------
My Solution:
- (void)mouseDown:(NSEvent *)event
{
timer = [NSTimer timerWithTimeInterval:0.1
target:self
selector:@selector(timerControl)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
NSPoint p = [event locationInWindow];
downPoint = [self convertPoint:p fromView:nil];
currentPoint = downPoint;
[self setNeedsDisplay:YES];
}
- (void)timerControl{
NSEvent *e = [NSApp currentEvent];
NSPoint p = [e locationInWindow];
currentPoint = [self convertPoint:p fromView:nil];
[self autoscroll:e];
[self setNeedsDisplay:YES];
}
/* now using a timer to smooth scrolling
- (void)mouseDragged:(NSEvent *)e
{
NSPoint p = [e locationInWindow];
currentPoint = [self convertPoint:p fromView:nil];
[self autoscroll:e];
[self setNeedsDisplay:YES];
}
*/
- (void)mouseUp:(NSEvent *)e
{
NSPoint p = [e locationInWindow];
currentPoint = [self convertPoint:p fromView:nil];
[timer invalidate];
[timer release];
timer = nil;
[self setNeedsDisplay:YES];
}
//////
@interface StretchView : NSView {
NSBezierPath *path;
NSImage *image;
float opacity;
NSPoint downPoint;
NSPoint currentPoint;
NSTimer *timer;
}
@property (readwrite) float opacity;
- (NSRect)currentRect;
-(void)setImage :(NSImage *)newImage;
- (NSPoint)randomPoint;
@end
- Mark said the following on Mar 11, 2009:
(comment made on this page)
Apologies: I started getting allocation
errors
Chapter 24 Challenge page 316:smooth Scrolling autoscrolling mouse Correction to mouseUp
----
Please read note at [timer invalidate] in
mouseUp: below.
I believe this solution is good, if you use
the solution posted by me a few minutes ago
and use the mouseUp: found below. As I see it,
the error came from releasing the Timer obj
twice; once through [timer invalidate] and once
explicitly as you see now commented out below.
Mark
- (void)mouseUp:(NSEvent *)e
{
NSPoint p = [e locationInWindow];
currentPoint = [self convertPoint:p fromView:nil];
[timer invalidate];//Stops the receiver from ever firing
//again and requests its removal from its NSRunLoop object.
// releases timer as well
//[timer release];
timer = nil;
[self setNeedsDisplay:YES];
}
- LiamG said the following on Mar 13, 2009:
(comment made on this page)
The new Xcode 3.1.2 does not seem to offer NIBs as an Add File option any more; only XIBs. So, the workflow approach from 3rd edition doesn't work: the template Cocoa project doesn't provide main.nib so you can't double click on main.nib and drop into Interface builder. If you add an XIB to the file, it won't add it to the NIB Files tree. So when you build the code, your XIB file doesn't get called at awaken. No Apple docs anywhere I could find. Anyone have a solution to this? - Tony Langdon said the following on Mar 17, 2009:
(comment made on this page)
Chapter 28 (3rd Edition) page 361. I needed to also set the target of the NSMenuItem otherwise I couldn't select them in the popup.
.....
[mi setTarget:self];
.....
I had set the target for the popup to the File's Owner changeViewController: and initialised the NSMenuItem with the selector but as I say without setting the target the menu item wouldn't work.
- rich said the following on Mar 27, 2009:
(comment made on this page)
I have bought this book. Very educational. The only thing is where can I download the codes? I found it very cumbersome to have to type in the codes by hand as I have a injured right hand. - Steve said the following on Apr 6, 2009:
(comment made on this page)
Chapter 11 - Basic Core Data
Has anyone gotten the examples code for Chapter 11 (CarLot program) from the Cocoa-3rd.tgz solutions download available from this web site to run properly. I've run into an error getting a sheet that pops down from the top of the window when I enter a price. This says "Formatting Error" with the options of "Discard Change" and "OK". I get the exact same behavior when I try running the sample code downloaded from the bignerdranch.com, so I don't think I'm doing anything wrong. - Steve said the following on Apr 6, 2009:
(comment made on this page)
Rich, you can download the code for the book from www dot bignerdranch dot com, then clicking on the books link, then clicking on the "Get the solutions" link in the information about this book. I'd post a direct link, but the comments won't let you include URLs (to cut down on spam, which is a good thing).
Steve
- Chad K said the following on Apr 9, 2009:
(comment made on this page)
Chapter 8 Challenge #1 threw me as well as several of the people commenting below. I could not figure out how a "key path" was the answer. Indeed, as it turns out, the "trick" seems to me to be to use the "silly" dot notation that was dismissed on p. 118. - FelixLeiter said the following on Apr 22, 2009:
(comment made on this page)
Dot notation is "silly" when used as a substitute for the standard Objective-C square-bracket syntax when used in Obj-C statements. But in the case of key paths, it sets them apart. Context is everything. - Richard Fuhr said the following on Apr 28, 2009:
(comment made on this page)
In working through the example in Chapter 2 ( pages 28 and 29 ) I have added the awakeFromNib method to the file Foo.m so that the textField will be initialized to the date. However, when I build and run the program, the awakeFromNib method is not getting called. I must be missing something, but am not sure what. - Richard Fuhr said the following on Apr 28, 2009:
(comment made on this page)
I found my problem, which is one of the common programming errors that the author warned us about on page 7, namely, capitalization mistakes. I had entitled my version of the method awakeFromNIB and it should have been awakeFromNib. The compiler did not care; it just thought that it was another method, and of course it didn't get called. After changing the name of the method to awakeFromNib it got automatically called. - James said the following on Apr 29, 2009:
(comment made on this page)
I typed in the code in chapter 33 (the OpenGL + Cocoa chapter) created all the Interface Builder stuff required, and yet what I'm getting when the OpenGL objects draw on the screen is not what the book shows what should be drawn!
Am I missing anything???
Also, is there any way to have the book code put into a tar or zip file, so that comparisons can be made between the readers code and the books code? I don't see why this hasn't been done! Other authors do it.... There are so few Cocoa books out there... - M Morgan said the following on May 14, 2009:
(comment made on this page)
This is an issue which may have been addressed in edition 3 but in edition 2 on page 160 in Chapter 8 (Loading and NSKeyedArchiver) I found it was not enough simply to edit loadDataRepresentation to make the code work.
I had to edit the readFromData method and add a call to loadDataRepresentation along the following lines:
if (![self loadDataRepresentation ...]).
I've just created a fresh objective C document project and notice that the readFromData method is still pretty much empty.
A great book and I've now more or less re-written a Carbon application I've been working on with a fraction of the code.
- Jefferson Humber said the following on May 23, 2009:
(comment made on this page)
The problem with the number formatter on p130, defaulting the expectedRaise to 500% under can be fixed by setting the multiplier to '1' under the number formatter attributes.
- Nate Lockwood said the following on May 27, 2009:
(comment made on this page)
I use Borland/Code Gear C++ Builder at work but bought a mac a couple of years ago and tried to learn Objective C and Cocoa but got really frustrated with the book I bought and quit. My supervisor is encouraging me again to learn to program on the mac so I found a highly reccommended tutorial and book, Aaron's.
I started the tutorial today. It starts out with links to the Apple tutorial but it has not been updated to X-Code 1.1.2 (there's a note to that effect) so the instructions are wrong at one point and I can't get past it. This is where lines are drawn which, I suppose, to bind the graphic to the code.
Before I purchase this book I need to know if I'm going to have the same problem.
TIA
Nate - Nate Lockwood said the following on May 27, 2009:
(comment made on this page)
That would be X-Code 3.1.2...Sorry. - Derek Sanyo said the following on Jun 14, 2009:
(comment made on this page)
On page 255 the beginSheetForDirectory: method states a types: member, but under 10.5 & X-Code 3.1.2 this isn't required.
Has anybody else found this to be the case? The Apple documentation still mentions it however as required......
- mdeh said the following on Jun 21, 2009:
(comment made on this page)
Cary,
Try:
[anotherTextField bind: @"value" toObject: self withKeyPath: @"fido" options: nil]; - mdeh said the following on Jun 21, 2009:
(comment made on this page)
Wrong page - Greg Henderson said the following on Jun 25, 2009:
(comment made on this page)
I am still new to Objective-C and would just like to put my mind at ease. it seems the first documented app, random, has two methods which aren't really related. One displays Seeded and the other display a generated random number but there is nothing in either IBAction methods that used each other. The see IBAction just displays a seeded message and the other performs some math and displays the random number. At first look, I was expected there to be something action 1 does to help action 2 calculate. What each method does have in common is changing the label test.
greg - Oliver Schneider said the following on Jun 30, 2009:
(comment made on this page)
Hi,
I’ve the German version of the book, so I can’t give any page numbers and of course I can’t cite precisely ;-)
I’m stucked by the first challenge of chapter 6, and this is not in the downloads. Everything is easy, but how can I create a delegate of NSWindow? I’ve
• created a window in Interface Builder
• created a NSObject in Interface Builder and tied it to the class AppContrroller
• connected them as delegate in Interface Builder
So, how does my code (e.g. class AppController) know about being a delegate? Where is the created NSWindow so that I can call the [window setDelegate:self] method? Just having “IBOutlet NSWindow *window” in AppController.h doesn’t do the trick :-(
Cheers,
Oli
- Oliver Schneider said the following on Jun 30, 2009:
(comment made on this page)
Just some additional information:
• In Interface Builder: Window delgetes to AppController
• In Interface Builder: And an Outlet connection (Window to AppController)
This code
#import
@interface AppController : NSObject {
IBOutlet NSWindow *window;
}
@end
#import "AppController.h"
@implementation AppController
- (NSSize)windowWillResize:(NSWindow *)sender
toSize:(NSSize)frameSize
{
//NSLog(@"Das Fenster ist %f breit und %f hoch.", frameSize.width, frameSize.height);
return frameSize;
}
@end
Does not compile:
Building target “Delegate” of project “Delegate” with configuration “Debug” — (2 errors)
cd /Volumes/oli.schneider/Documents/Computer/Programmieren/Cocoa/Delegate
setenv MACOSX_DEPLOYMENT_TARGET 10.5
/Developer/usr/bin/gcc-4.0 -arch i386 -isysroot /Developer/SDKs/MacOSX10.5.sdk -L/Volumes/oli.schneider/Documents/Computer/Programmieren/Cocoa/Delegate/build/Debug -F/Volumes/oli.schneider/Documents/Computer/Programmieren/Cocoa/Delegate/build/Debug -filelist /Volumes/oli.schneider/Documents/Computer/Programmieren/Cocoa/Delegate/build/Delegate.build/Debug/Delegate.build/Objects-normal/i386/Delegate.LinkFileList -mmacosx-version-min=10.5 -o /Volumes/oli.schneider/Documents/Computer/Programmieren/Cocoa/Delegate/build/Debug/Delegate.app/Contents/MacOS/Delegate
Undefined symbols:
".objc_class_name_NSObject", referenced from:
.objc_class_name_AppController in AppController.o
"_NSApplicationMain", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
".objc_class_name_NSObject", referenced from:
.objc_class_name_AppController in AppController.o
"_NSApplicationMain", referenced from:
_main in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
Build failed (2 errors)
So, how can connect to the window? I’m looking now since ours (in the book, in the internet), but no chance to get a hint…
Best
Oli
- Oliver Schneider said the following on Jul 1, 2009:
(comment made on this page)
O.k., I could solve the problem without solving it ;-) …and yes, I know, it wasn’t a compiler but a linker problem…
After deleting of nearly every code I got the same error messages. So I started again from the scratch and it worked immediately (less than ten minutes). The resulting code is exactly the same as the one I posted.
No, I don’t know want went wrong. I’m experienced with C, C++ (Qt, KDE) and Python, but I can't see what the problem is. Maybe later, after having finished the book ;-)
But I think this is a good example how someone can shoot in his own foot without knowing. I think there happened something strange with the Interface Builder… Magic is very good as long as it works, but if there happens something strange, it’s a huge problem if you can’t look behind the scenes (or maybe in this case, you don’t know where to look).
BTW: Nice book, and the German translation is also very good :-)
This site is driven by Techstra. Copyright © 2008 - 2009. All Rights Reserved.