BTNumbers: A Document-Based Number Crunching Program With Threads
[Update: A reader pointed out to me that these are called Armstrong Numbers]
My next project takes its name from the fact that it is going to do some number crunching. Its purpose in life is to calculate Bagelturf numbers, about which more later. It is also going to have a multiple document interface and use an NSTableView to display results. So I'm going to have to be able to understand threads, opening and saving documents, and all sorts of other things to make this work. Here is the spec:

I've noticed that all my header files have that __MyCompanyName__ string in them. Like this:

How to change it? A quick Google reveals the answer. Go to the terminal and type "defaults write com.apple.xcode PBXCustomTemplateMacroDefinitions '{ORGANIZATIONNAME = "My New Company Name" ; }'" without the outer quotes. Done.
Since I am creating a document-based application this time around, I have to start with a different template, a Cocoa Document-based Application template. It creates a set of file similar to those I had on my previous projects, but now there is a default class present: MyDocument. And there are two nibs, MainMenu.nib and MyDocument.nib. From what I understand, the structure of the objects is slightly different too. Instead of the application object creating a window controller, loading a nib, etc., all of that is handed off to the document controller. The application manages the document objects.
There is a lot of information in an Apple document entitled, not surprisingly Document-Based Applications. A lot of information indeed. A document-based app is much more complicated than a simple app. I'll be tackling that later, but for now, I need a user interface. Here is my effort:

A new window appears with Select as the selected item for Order and Base so the user is prompted to select some numbers. The Reset and Start controls are dimmed and the calculation status (shown as Calculating) is hidden. The progress indicator is hidden too, and the table is blank. The found status at the bottom is hidden as well.
Once both Order and Base have been chosen, Start becomes active. Clicking Start initiates calculations and the progress indicator and calculation status of Calculating becomes visible. The found status says Found 0 Bagelturf Numbers. The Start button turns into a Pause button, and Reset becomes active. The progress indicator moves left to right. The Order and Base poups are dimmed.
Clicking on Reset takes everything back to the start, as though a new window had been opened. I'll put up a dialog if any Bagelturf numbers have been found. Clicking on Pause halts calculation and changes the button to Resume. The status says Paused. Clicking Resume continues calculation and the button changes back to Pause. The status goes back to calculating.
As numbers are found, they are added to the table, on the left in the base set for the calculation, and on the right in decimal. The found message counts the number found. Once calculation is complete, Pause changes back to Start, dimmed. The calculation status changes to Complete. The Reset button is dimmed.
I am going to make this window resizable because in small bases and large digit counts, the results could get pretty long. That will involve dealing with springs and struts in IB. The size panel in IB's inspector lets me set up a minimum size:

I don't think I have to change anything else. New windows will be autopositioned.
if I "run" the interface in IB, I can play with the size and see what happens. This happens:

Not so pretty. I need to make the table stretch, but do other things for the other elements. The pop-ups should remain central at the top; the Reset and Start buttons should stay at the edges; the lines and the progress bar should stretch; the status and found messages should stick to the left edge. Everything should stick to the top except the found message.
Setting the springs just takes a little experimentation. Command-R in IB runs the interface and lets me resize the window and check out its behavior. Command-Q restores normal operation. There are a couple of problems remaining thought:

The static text Order and the popup are getting separated as the window stretches. And the other problem is that the Result column of the table does not share the new width with the decimal column. Ideally the decimal column would remain static (since the program can only handle numbers up to 2 billion since I will use 32-bit ints) and the Result column stretch.
The setting for the table sizing applies to the NSScrollView that encloses the table:

By clicking inside the table and onto the Decimal column header I can drill down to the column itself (an NSTableColumn object) and then I get what I am looking for:

I'll set the minimum and maximum to 100 for the Decimal column and adjust it if necessary later. I'll leave the Results column alone. Rats. It doesn't stick to the right side and stretch the Results column. I will probably have to do that in code.
The cure for the stretching space between the static code text and the popups is to use a box. Select all four elements and go to Layout->Make Subviews Of -> Box. Then make the box invisible, remove the title, and set its springs. Now that is fixed.

Here are the settings for the box that encloses the pop-ups:

Next: figure out how I am going to communicate with all of this. Outlet/action? Bindings? I'll have to be careful with the names too, since the buttons change their action.

I've been thinking about the high level design of this program. It's not as simple as the others I have tried, so I'll actually have to think about its structure and do a little planning.
First though, I found a fix for the table column problem. I could not make the rightmost column stay the same width while the leftmost scaled with the window. I was looking in the wrong place. Double-clicking carefully on the table gets me to the NSTableView (not the NSScrollView or the NSTableColumn). The I adjusted the settings as shown.

And now it works. Note the resizing mode setting. I also turned off the horizontal scroll bar: stretch the window if you needs to see more.
Reading through the list of what happens when various interface items are clicked made me start to think about how to implement all this. It looks like a lot of code, spread all over the place. Not a good design. But it can be broken down into a set of distinct states and connected together in a state diagram. Still a lot of code, but this time table-driven, and all the complexity in one place. Then I started reading about swapping nibs to get different interfaces. Interesting, but complicated. Finally I hit on another way to go: use a tabless tab view.
If I create a tab view and use the Inspector to set it up, I can get rid of the background and tabs completely. Now by pasting my interface onto each page and editing I can set up everything I need for the different states. This drives some of the interface for me. I can channel all of the actions for a single control on all the tabs into a single method and give the tags appropriate values (no need to differentiate between them). The table and the Found status can be left off the tab view, since the table does not change, and the Found status has to be programmed anyway. Also the pop-ups don't change except for being disabled as I move out of the initial state and enabled when reset.
This leaves me with the lines (which don't change), the Calculating status which is static except for state changes, the progress bar, and the buttons. Now I'm thinking this is getting messy too. The tab views will be hard to manage if I want to make changes, and I may end up with a lot of outlets.
One thing is sure though, I want to have a separate object handling this view and to control it with state messages from my custom document controller. I will need methods to do a range of things too, including getting the pop-up settings, setting the progress bar, reacting to buttons, and filling the table with results.
So I create the BTDocViewController in IB from the Class menu and set it up. I can use bindings to control the pop-ups and the table. This may save a lot of coding, even though I don't fully understand bindings yet. I can bind to the buttons too. The bindings include title, action, enable, etc. Here are the available bindings for the Start button:

By hooking these up appropriately to BTDocViewController I can control and react to the buttons.
Another part of the high level design is going to be concerned with doing the calculation of Bagelturf numbers. Initially I will want to do this on the main thread, then, as an exercise in confusion, move the calculation to a separate thread so that the interface remains alive. So I will need an object for the calculation. Let's call that BTNumberCalculator. Start, pause, and reset can, I hope, be implemented via the object that controls the thread. But I will still need to perform progress bar updates, send initial values, and get back bagelturf numbers as they are calculated. My choices here are limited, since much of Cocoa is not thread-safe. At least the data I need to pass is small.

I've decided that some interface elements will need actions so that I can act on them when they are changed. I don't think I can do the things I want to do using bindings because bindings only tie data values together. The Order, Base, Reset, and Start buttons will all need actions, so I set those up. Select the custom controller class in IB:

and use the Inspector's Attributes pane to set the actions:

These actions will need methods in the BTDocViewController class, so I can generate those in IB by using Class->Generate Files and accepting the defaults. For the other interface elements I will use bindings. That's probably not the best choice in all cases, but I am eager to learn and I think that I understand them now.
So lets design the state machine that the view controller will run. I count five states and eight things that need changing:

I will put the implementation of the states into the BTDocViewController. The interface to that controller will be the new state. That leaves the problem of how the BTDocViewController object tells the MyDocument controller that something needs doing, such as calculation starting or stopping, or communicating status, such as Complete. Maybe I can give my controller a delegate and make MyDocument a delegate?
The states transitions are pretty simple, as below. Go to the state in the table from the state in the heading when the lefthand action occurs:

There will be some additional state involved in deciding whether Order and Base have both been clicked, and that state will be reset by a transition to the Initial state. In addition, since the range of the numbers that can be calculated is limited, not all numbers will show up in the pop-ups. If the Base is 36, then any order larger than 5 will overflow 32-bit signed arithmetic, for instance. But I do not want my view objects needing to know anything about the implementation of the math, so that logic will have to be encapsulated in my calculation object. In that way I can improve the number range with no changes to the other objects. So I create a new class in XCode called BTCalculationEngine and set it up with two empty methods:

I will fill the methods in later (when I know how they should work!). For initial testing I will put some static arrays in there. So here is my skeleton BTDocViewController interface:

And the implementation:


I missed a state transition: the one that includes the calculation finishing. The correct transition table is:

I also realized that the calculation engine methods legalBaseChoice:for Order and legalOrderChoice:for base should be class methods. Since they are just utility functions not tied to any particular instance.
Now to coding the interface to match the state table. As I think about coding this I can see that my states are all wrong. A alternative way of handling the states is to simply use NSStrings and encode the table as a NSDictionary keyed by state string containing NSDictionaries of instance variable values keyed by name. Now when sent a message to change the state I can look up the state and iterate through the selected dictionary setting the instance variables.
Or maybe I can get the bindings to do all of this for me. If I bind the dictionary selection to the state string, then I should be able to select the correct item in the dictionary automatically. Then maybe I can bind the individual display elements to the dictionary selection using a key path of some sort.

I coded the state table into a dictionary of arrays and created accessors for all of the interface elements to be bound to. Then I wrote code to look up the state string as a key in the dictionary and access the array elements by index to know what state to set the view elements to.
Only it doesn't work because on the second state change the application crashes. I know it is a memory retain/release problem, but for now I have run out of time debugging it. I'm pretty sure it is an autoreleased object getting released when I don't want it to be.

It was a simple memory retain/release error. I'm still thinking in terms of static variables, when in this object-oriented world there are very few. I had written my -awakeFromNib like this:

but had omitted the [machineStateIEs retain] line. So the first -changeViewStateTo worked, but the second had no object since the autoreleased NSDictionary had been released by the run loop. I also added a balancing [machineStateIEs release] in -dalloc of course.
The Found... strings will be fixed later since I will use those as formatting strings for the number found.

I am updating the state from the dictionary of arrays with this code. Each item that is a NSString is just passed to the accessor. The others test the length of the string and pass YES if non-zero. Another way I could do this is to store the YES/NO values as strings in my object and have a value transformer that converts "YES" to YES and anything else to NO.

Next I want to be able to have the code correctly set up the pop-ups for Order and Base. I will do that in -awakeFromNib and will call the class methods legalBaseChoicesForOrder and legalOrderChoicesForBase. But first I have to code those.They are necessary since the calculation engine has a limit on the largest number it can handle. I make these class methods because they are not associated with any particular object: they reflect the ability of the entire class as implemented.
Since I am using 32-bit ints, the largest number I can represent is 2 to the power 31 minus 1, about 2 billion. With no Base defined, Order (the number of digits) can be 2 to 31 since the smallest Base is 2. So if Order = 0, Base = 2 to 31. With no Order defined, Base can be anything from 2 (binary) to whatever I can represent, say 36 (0..9 and A..Z).
So I define some symbols:

and then use them in this code that calculates what is legal:

I don't have enough code to test this yet. Although choices is a mutable array, it lets me return it as an immutable array. I assume it is doing the Right Thing for me here, whatever that is. I autoreleased the choices array so that the receiver can retain if needed.
I don't have any outlets between the view controller and the pop-ups yet. I am hoping that I can figure out how to make bindings work so that I just update arrays and the content of the pop-up follows. That is the next task.

I created an object to do the calculations for this application, but have realized that I have not thought out the interface to it carefully enough. Currently the two methods I have written return NSNumber objects for the valid values -- not good. Since only BTCalculationEngine knows the size of the numbers and how to express them to the user, I should have the complete interface be NSString objects. This also allows the calculation engine deal with localization, if I wished to add that.
So I replace my array building loop with this:

which will fill the array with strings containing the values. I can use that to populate the pop-up directly:

Since setBaseChoices retains the new object, the autoreleased array returned by BTCalculatuonEngine should stay allocated. That in turn will retain the strings. I set up bindings for Order and base pop-ups as below:

I had hoped that setting the No Selection Placeholder would display "Select" initially, but that did not happen. I suspect that this is because I have not bound the control to an array controller (content). The fix will be to add the string "Select" into the array and remove it when the first choice is made.
So what happens? Both pop-ups display correctly, showing a list of numbers as calculated. So far so good., However after I set the pop-up actions to -baseChosen:sender and -orderChosen;sender and selected new numbers, I got a crash. The action methods are never called.
The error was a simple one: memory allocation again. The autorelease I was adding to the array of strings was bogus: it is already autoreleased, so no need. I was over releasing it. Here is the corrected code snippet:


I reorganized my code. My BTDocViewController was serving no useful purpose, so I moved its content over to the MyDocument object. I can understand the value of encapsulating functionality inside custom view objects, but what I was doing -- delegating some code to another controller -- was not worth the effort. So now I have two objects: MyDocument which is my controller, and BTCalculationEngine which is my model.
I also threw out all my code for handling the "Select" pop-up string and replaced it with bindings. I had made a design blunder that caused me to do this: the Select string was being added in one place (the model) and removed in another (the controller). What I replaced it with is illustrated by the action code for a Base choice:

This extracts the chosen Base string, sends it to the calc engine to get an array of valid Order strings, sets the chosen Order to the one stored in the model, and sets the Base string in the model. The setChosenOrder message is needed because updating the string array causes the bindings to select the first element. The rest of the work is done by bindings. I set up the bindings for the Order pop-up like this:

orderChoices is the NSArray of NSStrings generated by the model. chosenOrder is the Order chosen by the user by clicking the pop-up. By binding the selectedValue of the pop-up to a variable in my controller I can make it automatically present and dismiss the "Select" string:

See the Null Placeholder box at the bottom. When the Reset button is pressed I run this code:

This sets the chosenOrder and chosenBase to nil and that, via the bindings makes the Select placeholder appear again. Note that my interface with the calculation engine is now completely NSStrings. Passing a nil NSString generates all the possible orders or bases.
My document instance variables now look like this:

I can actually use an NSArray instead of a NSMutableArray now I have stopped trying to modify the array myself. I also has to create an instance of the calculation engine. I did that in -awakeFromNib and released it in -dealloc.
So what doesn't work? The only problem I have is that the pop-up, when displaying the Select string has all the numbers above it, not below as you would expect. I don't know how to fix that. An improvement I can make is to bind the controller's chosenBase and chosenOrder to the model's baseString and orderString. I will have to do that programmatically because IB is not there to help me, but once done, the view change will update the model with no code needed in the controller since the two bindings will propagate the change through. Maybe if I can do that, then I can make it work for the sting arrays as well.

More reorganization and changes. I have simplified the use of my state table by using value transformers in the bindings and converting all my BOOL variables to NSStrings. I have created two value transformers: StringToBoolTransformer and StringToColorTransformer. Here is the latter. The interface code looks like this:

And the implementation code like this:

This returns a color depending on whether a string starting with "Y" or "y" is passed. So since my table of states has strings with "Y" when I want something enabled, I can set up the bindings in IB like this:

This is bound to the static text that says Order and Base. Now when the pop-up is disabled, the text goes grey. I did a similar thing with the Start/Pause button, binding its enabled state to a string via the other value transformer. So now my code for updating the state looks like this:

I simply pass the strings through. To set up the value transformers I had to add this method to MyDocument:

+initialize is called once for each class. This registers the transformers with the NSValueTransformer class and makes them available to bindings.

I created an object for my Bagelturf numbers, BTBagelturfNumber, and in doing so reorganized a great deal. Why do I need an object for my numbers? I need to keep the calculation, and storage of them separate from the view and the model since I want the implementation to be completely independent. Here is the interface to BTbagelturfNumber:

All you can do is initialize one with a decimal value string and a base string and then read out the decimal value and a representation of that value in the base. This will allow me to show the numbers in the table without having to manipulate any math and without knowing anything about what the number is or how big it is. I will probably have to make this object conform to NSCoding and NSCopying, and implement isEqual to make it work with everything else I want to do.
The implementation is below (untested!). I omitted the accessor code:

I copy the valuestring straight into the object. I believe that retains for me, so I don't have to add one. Then I start with an empty mutable string (nativerepresentation) and add ASCII characters to it, shifting right, so that the least significant digit is at the right (highest index in string). Then I assign the finished string and retain it in my object. The dealloc releases the strings.
The next thing I changed is the BTCalculationEngine. The name I gave it is a very functionally-oriented name, not object-oriented, so I changed it and created a set of methods for it. I now call it BTBagelturfNumberFactory, since that is what it is: a factory for creating BTBagelturfNumber objects. Here is the interface:

The class methods are there, as before. The factory is created with the Order and Base and deallocated when it is no longer needed. To tell it to do calculations, I added the method -generateInNextRangeOfSize. rangesize tells the engine how many numbers to test. Any Bagelturf numbers it finds are created as BTBagelturfNumber objects and returned in an array. Each time the method is called it starts from where it left off. I did it this way because it will let me break the calculation up into chunks -- I don't yet know how I am going to make the calculation run while keeping the interface alive. Passing rangesize of zero will let the calculation proceed to completion. The -progress and -complete methods allow me to query the factory object to see how far calculation has progressed (as a fraction of the possible numbers) and to find out whether it has exhausted the possible numbers.
I won't post the whole code here (it is long and not yet debugged), but here is the part where it creates a BTBagelturfNumber when it finds one:

I think I got the alloc/release right. I explicitly allocate the strings and then explicitly release them. I don't want to use the autorelease pool because I could be doing this many times as calculations proceed. The -initWithValue:andBase method does retain the strings.
Now the problem is how to run the calculations on multiple document windows, updating the progress bar, and the number found, while being alive to process clicks on the buttons.
I think what I need to do is to create the number factory on a new thread. That thread puts calls to -generateInNextRangeOfSize in a loop and adds a short delay to give the CPU time to keep the interface (on the main thread) active. It also tests to see if calculation is complete. If it is, it exits. I can use -performSelectorOnMainThread to update the array of results (and hence via bindings the table) and the progress bar.
One thing I am not sure about is how to implement Pause/Resume. One way may be to sample the state of the state machine. If it is Pause then don't do any more calculations and do sleep a while. If it is Calculating then continue as normal. if it is Initial then the reset button was pressed so exit.
By my reckoning I have three major items to complete: multithreaded operation, displaying results using bindings, and saving/restoring from disk (since this is a document-based app).

I posted completely brain-dead code the other day, as I found out when I debugged it. Programming while tired. Here is the working version:

I tried to get results to show up in the table now my code is generating some. For the purposes of debugging I created a -calculate method and stuffed some code into it that ran the calculations 100 at a time and put the results in the bagelturfNumbersFound array:

For Base 10 and Order 7, that's seven digits, 9 million numbers, it processes the whole range in about five seconds. The code for searching is very naive and unoptimized, so probably a factor 10 speed up is easily possible. Then I hooked up the table to the array of results by doing this:
1. Drag a NSArrayController into the MyDocument nib.
2. Add nativeString and decimalString as attributes of the NSArrayController and change Object Class Name to NSMutableArray and select Automatically Prepares Content
3. Control drag from the NSArrayController to File's Owner and select the content outlet.
4. Selected the Result table column header and filled in the binding for value as Bind to: NSArrayController, Controller Key: arrangedObjects, Model Key Path: bagelturfNumbersFound.nativeString
5. Repeat for the Decimal column header with a different Model Key Path setting.
The result was interesting (and incorrect):

Clearly there is something I don't understand about binding array controllers and tables. If I repeat with a hex base, then the result column correctly shows hex, so at least that works. Somehow I am telling the table columns to put the entire array into one entry. So try again:
1. Drag an NSArrayController into the MyDocument.nib window
2. Add nativeString and decimalString as attributes of the NSArrayController and change Object Class Name to BTBagelturfNumber
3. Bind the contentArray of the NSArrayController to File's Owner (MyDocument), Model Key Path bagelturfNumbersFound
4. Select the Result table column header and fill in the binding for value as Bind to: NSArrayController, Controller Key: arranged Objects, Model Key Path: nativeString
5. Repeat for the Decimal column header with a different Model Key Path setting.
Nothing. I suspect that I am leaving something out, since I get no errors, but I cannot see what. The table columns are bound to the arrangedObjects and the array controller the contentArray. I have the correct object type set up. Maybe I have to provide accessors for my array -- but it is not a custom class, just an NSMutableArray.
Changing my update of the table to this code worked:

The problem was that I was bypassing KVO: nothing was being notified that the array contents had been updated, and so no table display. Here is what the final result looks like:

I don't get a progress bar when it is calculating, and the spinning pizza appears after a while, but I expected that: I'm not letting the interface update because the run loop isn't being run.
Another problem: the columns do not sort in the right order. They sort using alphabetic sorting instead of numeric sorting, so when I use other bases, this happens:

The "1" numbers are at the top. The Result column will not have this problem because it always has rows with the same number of characters.

To implement the Found string, I used bindings again. I removed the binding that existed (value to a string in my controller) and set up a new binding like this:

This substitutes the count of lines specified in the model key path for %{value1}@ in the Display Pattern. This works:

but it has a flaw: if one number is found, it says Found 1 Bagelturf Numbers. The "s" is there. Also when none are found it would be nice if there was no string. I found I could implement that like this:

An array item is removable if there is at least one, so I invert that with the NSNegateBoolean value transformer and use that value to control the hidden attribute. I can change the string on the other binding to remove the plural by changing it to "Bagelturf Numbers Found:" But this has a problem. If I click away from any of the found numbers then the string is hidden, since canRemove needs at least one number selected. But this setting does work:

I simply use the fact that FALSE is zero and invert the @count.
I discovered that I can disable sorting on the table using a hint on http://homepage.mac.com/mmalc/CocoaExamples/controllers.html (Disabling sorting in a tableview).
Now I'd like to disable selection completely on the NSTableView. I don't want either the highlighting or any selection to be made. I found this comment: "You can disable selection by always returning NO for the tableView:shouldSelectRow: and "tableView:shouldSelectTableColumn: delegate methods." So in theory I can set up an outlet to the NSTableView, make self (MyDocument instance) the delegate, and implement those.
So in the MyDocument.nib file, click on File's Owner and select Classes tab. Add a new outlet called tableView of type NSTableView. Now go back to the Instances pane and control-drag from File's Owner to the table view. Click Connect and the outlet is connected. I still have to add the instance variable to MyDocument. That is done like this:

So in -awakeFromNib I can set MyDocument to be the table view delegate:

The delegate code looks like this:

And this works -- up to a point. It does prevent selecting the table, but when the table first is filled, there is a selected row. I guess I will have to do something to the array controller to prevent that. I had another go at the array controller attributes and came up with this:

This seems to work. Now the results look like this:

No selection border, no selected row, and the count in place. The next challenge is getting the calculation to take place in a separate thread.

I found an answer to my problem of how to change the text for the count of Bagelturf numbers depending on whether one was chosen or more: "1 Bagelturf Number Found" -> '2 Bagelturf Numbers Found".
The trick is to maintain an outlet to the array controller so that the number of items in the controlled array can be obtained. Write a method to return either an empty string or "s" depending on the number. Now create a display pattern that binds to the method and put that string into the display pattern in the appropriate place.
Here is my method. I didn't have to create a setter since it is never called:

I set up the disply patterns for the "Found" string like this:

Expanding the two display value items gives:

And this is how the result looks for one number found:


I've now made my application run with a separate thread. And a crash. The search works all the way to the end and then crashes. Also there are some interface problems. This is not to be unexpected since I made the change without thinking about what is thread safe and is not and how the thread should communicate with the main thread. Here is a screen shot of it working:

I start the thread like this:

And implement the thread itself like this:

I have some code commented out that I thought might be needed. The sleep was not needed to keep the interface alive. Also I thought that the state change was causing the crash, so disabled that. The code tests 100,000 numbers and then does updates.
One way to handle the progress bar and other things is to do them from a method called by a timer. I can call the -progress method in the timer method and update the progress bar. But this may have the same thread problems that I have now. I'm pretty sure that the crash is coming from my deallocating something that is still in use. I have also not thought out how to implement the pause function or handle reset or completion.

Better Threading
If I limit the calculation to short spans, such as Base 10 Order 4, I get no crash. Base 10 Order 6 crashes. I also get this message:

indicating that this is definitely a memory allocation problem -- probably a double release. The crash report gives this:

It is my thread that is crashing, and it appears to be at the [pool release]. And I think I found and corrected the bug. The crash occurred much more often if I paused and resumed the calculation. So I looked at the NSDate code I had used and realized that it was releasing autoreleased object instances in an effort to prevent them from using up memory. This was fine until the autorelease mechanism did the releases. So the new code explicitly allocs and releases the NSDate object:

This checks to see if the state is Paused. If it is, then it sleeps the calculation thread. If not, it calculates.
I also have an overwriting problem. The count of numbers found is getting updated by bindings automatically and gets to look like this quite often:

So now I need to look carefully at how I update the array and the interface.

Getting things to run in separate threads seems to be a subject of much discussion and few simple answers. I posted a question in the Apple Cocoa list:

thinking that there should be a way to do things to threads. Create, start, control, destroy, the thread externally so that the thread contains only crunching code and is unaware of its environment, treating the thread like it was a nicely-bahaved object. I'm used to doing things that way with separate processes: fork it and send it signals or make it suspend or use locks to make sure that it does what you want. Kill it with a signal and have it take care of its own clean up. But no, it does not appear to work that way. Threads in Cocoa have to be wound closely with the main thread.
One approach posted by Ryan Britton used a flag called stopThread that was polled by the worker thread in its loop to abort the loop. It used an NSLock to lock access to critical sections of code so that the main and worker threads had exclusive access to data structures that were updated. And it also used the @synchronized directive to obtain exclusive access to a block of code. It used -willChangeValueForKey and -didChangeValueForKey so that bindings worked and it wrapped those in -performSelectorOnMainThread. No feature for pausing the worker thread.
Another post from Ben Haller suggested going behind the scenes and using PThreads (Posix threads). That would appear to simply bypass the interface provided by Cocoa and could be changed at any time.
J o a r suggested using NSConditionLock, a class similar to NSLock. This still requires a polling thread and won't do the quit of the thread, just the pause/resume. The suggestion to that was once it comes out of the lock have it decide whether to die or not.
Matt Holiday (who shamelessly copied my web site design) had this suggestion:

I like the idea of running my thread inside an object and having delegate methods. He suggests having delegate methods -didFinishRange and -didFinish so that I can perform clean up in my main thread. Again I like this. It is nicely objectified, something I had not done yet.
So my next task is to refactor the code so that I follow all the rules and apply locks where necessary.

Since I need to embed my calculation in an object to make threading work better, the easiest thing to do is to use the BTBagelturfNumberFactory class and add new methods to it for controlling and monitoring the calculation. I'm going to implement a delegate that is called when certain things happen, and am going to ensure that I run all the GUI updates on the main thread and use locks in the right places.
Here is a stab at a new interface for BTBagelturfNumberFactory:

I have gotten rid of the -initWithOrder:andBase method. Instead there is a plain -init and a -setOrder:andBase method.
The delegate is set using -setDelegate and is stored as the client instance variable. There are two ways to start a calculation: -startCalculation just runs to completion; -startCalculationWithRangeSize just tests a range at a time. The calculation can be aborted with -abortCalculation and can be paused and unpaused with -pauseCalculation passing YES or NO.
The delegate methods are called according to what is going on. -calculationDidStart and -calculationDidEnd are called once only at the very start and the very end of calculation -- always -- irrespective of how calculation s started and ended. If the calculation is aborted then -calculationDidAbort is called once. If the calculation is carried out one range at a time, then before each range is calculated -calculationInRangeDidStart is called, and after the range is calculated -calculationInRangeDidEnd is called. The latter returns an array of BTBagelturf number objects if any were found.
All delegate methods are called on the main thread.
Initialization of BTBagelturfNumberFactory objects now looks like this:

I will be adding some more code to -init later when I implement the delegate methods, but for the time beeing it just sets a few instance variables to default and safe values. -setOrderAndBase is very simple:

Further set up of the calculation will only be done when it is actually started. I also added this code to the end of MyDocument's -awakeFromNib:

Now I am creating the factory and the result array right at the beginning, rather than waiting for the user to press Start. The -dealloc method has been changes as well:

My -calculate method (with heavy editing) will move into the BTBagelturfNumberFactory class too.

Delegate Methods
To call my delegate as things happen, I have made a pair of methods for each delegate method that look like this:

The first method is called by the calculation code. It calls the second one on the main thread to avoid any GUI update and other issues. The second one calls the delegate method if it exists. The code for clientCalculationInRange is a little different because there is a results array passed back.
The clientFlags value is set up in -setDelegate:

This prevents the tests happening very often and will also handle a changing delgate. Here is my new -calculate method, the one that is called on a separate thread:

I call the delegate at the appropriate places and check three flags: calculationAbort, calculationPaused, and calculationComplete. These are modified by -abortCalculation, -pauseCalculation, and -generateInNextRange respectively. Pausing inserts delays but keeps checking for aborts. Otherwise calculation is performed and the delegate informed at the start and end of each range if ranges are used.

There are some calling patterns that I want to make sure are always followed. For example, each call to -calculationDidStart should be matched one for one with -calculationDidEnd. To enforce this I will have to take a careful look at how the calls are invoked in the BTBagelturfNumberFactory class.
-calculationDidStart and -calculationDidEnd will always be paired, as it turns out, since the program flow enforces it. A harder pattern to enforce is that I want exactly one call to -calculationDidAbort to be made for each call to -abortCalculation. I need these two paired because I can start the abort at any time, but will have to wait until the calculation reaches a certain stage before I can do much else. The way to implement this restriction is through locking.
There are two cases that have to be covered: a) calculation is still in progress and will pass through a call to -calculationDidAbort in a while, and b) calculation has already ended, so an explicit call to -calculationDidAbort is needed.

I added a flag threadEnded. This is also manipulated in a locked section of code. My lock is an NSLock, set up in -awakeFromNib. The logic counts calls to -abortCalculation and if calculation has already ended, performs an immediate call to the delegate. The code at the end of -calculate now looks like this:

After control exits the loop for any reason, any count of calculationAbort is matched by a call to the delegate method. The threadEnded flag is set in the locked section so that it is clearly connected with the abort code. Strictly speaking it does not have to be inside, but if it is not the order in which it and the abort count are manipulated is important (and easily wrecked).
Debug debug debug. After making some corrections (mainly caused by moving so much code around) I have an app that works threaded and keeps the interface alive. The progress bar progresses, I can pause and resume, and I can abort by pressing Reset.
Here are the delegates I implemented in MyDocument:

-calculationDidEnd transitions to the Complete state if it was Calculating. The other alternative is that it was aborted and is now in the Initial state.

-calculationDidAbort resets everything and empties the results array. This lets the user start the calculation again. Bindings take care of parts of the interface update, such as the table contents. The button press should prompt the user with a "do you really want to do this" alert so that calculations are not lost immediately.

-calculationInRangeDidEnd updates the progress bar by calling the number factory to get it (a float) and then stores any results that were found in the range. The results store is wrapped so that the bindings are aware of the new data and the display is updated.
The other delegates are not implemented.

Adding a warning to pressing the Reset button was pretty easy. I edited the Reset button click code so that it created a modal sheet for the window. The only hitch I hit is that informativeTextWithFormat cannot be nil: you have to use an empty NSString if you want it to be blank.

-beginSheetModalForWindow calls a delegate when the sheet is dismissed. You give it an object (self in this case) and a selector. In the -resetWarningSheetDidEnd code I simply test to see if the Reset button was pressed or not. This fits in well with the way that I have reorganized the program: I don't have to worry about what happens after I abort the calculation and I can abort from several places in my code with a simple call.
The way this is implemented, calculation continues while the sheet is up. This works fine. Here it is with the sheet:

Now I notice that when I pause the calculation, the program still uses CPU: about 3-4%. I think I can lower this by doing two things: stopping the animation of the progress bar, and changing my polling pause into one that stops on a lock until unpaused.
I tried that: no luck. You can't stop a determinate progress bar from animating. And adding a lock didn't save any CPU. It's the animated progress bar that takes all the CPU.

The next step is to be able to save and load my Bagelturf number documents. I want to be able to do a number of things:
1. Save and load a document that has finished calculating
2. Save and load a document that is in the middle of calculating (it pauses first)
3. Save Bagelturf number data as raw ASCII to a .txt file
4. Warn the user to save if they quit the application with unsaved data
5. Have the red close dot be marked when unsaved data is present
I'm also going to set up an application icon, a document icon, and clean up the menus so that all the extraneous items are removed and what is left is implemented.
First I'll set up an application icon and a document icon. For the app icon I start with a photo and use Photoshop to remove the sky, then drop the scaled result into Icon Composer. Icon Composer is a utility that is supplied with the developer tools. Then I scale and repeat to make the other sizes, dragging and dropping PSD files each time. The alpha channel is included in the icon and shown as red here:

Icon composer saves this as a .icns file. For the document icon I want to add the flower to a plain document icon. This is trickier and requires more specialized tools. I downloaded Iconographer and used it to get the icon from a plain text file.

Now I can export the 128 pixel thumbnail as a .PSD file and open in Photoshop, add a small version of the flower icon, and reimport it into Iconographer so:

And save as a .icns file. Then open in Icon Composer and drag the big icon onto the small icons to generate them. I know there are easier ways than this, Folder Icon X is one, but this is a quick and dirty exercise to get me something to use for my app.

So I have two .icns files: Flowerdoc.icns and Flowericon.icns for use in my app.

For my application to use the icons I created, I have to put them in the resources folder, English.lproj and tell the app that they are there.

Selecting the BTNumbers target in my project and opening the info window (click the blue "i" in the project window) and selecting Properties gets me this:

I have to edit this. Clicking on the purple ? brings up the relevant docs.. I have to change the identifier. I'll use com.bagelturf.BTNumbers. I don't need a Creator since I don't open any standard file types and don't want to appear in Open With lists for them. I add the flower icon file name and leave the class and nib names alone.
The document types I need to edit. I want to be able to write plain .txt files and have a binary format of my own. The first one I will create is one for Bagelturf number files. Document type is "Bagelturf Number Document". The UTI (Uniform Type Identifier) is specific to my app and document, so I can use my own: "com.bagelturf.btnumbers". Extensions I will make "bgtn". For a MIME type I will use "application/octet-stream" since I am going to be storing binary data. For OS Types I will use "bgtn" again. This is there so that files stored with no extension can be associated with the app. The Class is MyDocument. The Icon File is Flowerdoc.icns. Storage is Binary. Role is Editor, since I can open and change an close these documents. And I uncheck the Package box.
I am not certain that I need to create a Document Type for a plain text file since I will only be writing that.
I also have to add the icon files to my project by dragging them onto the Resources folder in the project window.
Here is the Properties pane set up. It is very wide, but not stretched out here:

And when I run my app, it does indeed have the flower icon.
The application name is actually set on the Build pane. I trid to set that to Crunchie, but then my app has no menu bar. If I change all the other occurrences of BTNumbers to Cruchie I still have the problem. Wierd. If I add a new executable and call that Crunchie, then I get an error No Executable Present At Path. The executable information window lets me set up a path, but I have no idea what it should be. I just put Crunchie.app into the window.
I eventually tried the full path: finding the Crunchie executable with Spotlight and then navigating to it:

This lets me run the program in XCode as "Crunchie", but it has no icon in the dock, and no menu bar.

There appear to be a wide array of choices as to how I save and load data. The way the document template was created, I have two methods already implemented for me waiting to be filled in:

If I set a breakpoint on -dataRepresentationOfType, and use Save from the menu I can see "Bagelturf Number Document" as the type, and the save dialog has bgtn as the file extension. The text gives me some other options and the recommended ones are -dataOfType and -readDataOfType.
But my document doesn't really have any data as such. I actually want to save and load the instance variables of MyDocument since I want to be able to save the current state of the object (and the model object) in order to be able to pause calculation and resume it. So I need to use an NSCoder. The recommended way to go with Tiger is to use NSKeyedArchiver and NSKeyedUnarchiver. These let you assign keys to each piece of data that gets written out and read back the data by key name. It's like a persistent dictionary.

In order to save and load my document I have to be able to save and load the objects it contains. This means making my objects comply with the NSCoding protocol. Starting with BTBagelturfNumber, I amended the interface file to look like this:

This includes the -encodeWithCoder and -initWithCoder methods and also claims compliance via <NSCoding>. Tiger records class versions into keyed archives, so I will set that up for this class:

That sets the class version to 1. If the program is modified and the data I need to store changes, I can use the version number to know what data exists and how to use it. To actually code and decode my object I use these methods:

Since BTBagelturfNumber objects inherit from NSObject there are some changes to what you would expect. NSObject does not comply with the NSCoding protocol. The encoding and decoding of the two strings could happen in any order since they keys are used to reference the data. The decoder simply uses the accessor methods to set the new decoded values, both NSStrings.

Now I have to do the same treatment for BTBagelturfNumberFactory. All the instance variables of this class that need saving are not objects, so the coder and decoder will have to be slightly different. One of them is a simple C array.

When the user selects Save from the menu then the document class will pause the calculation if necessary and then do the save. This will put the instance variables that are not saved into a known state. Here is the code for the encoder and decoder:

I have to convert the array of digits into something that can be coded, so I create an NSArray of NSStrings, each string being a representation of the int in the C array.
The next task is to make the MyDocument class save and load its contents.

Before I can save the data in my document I have to check to see if calculations are ongoing. If they are then I must pause the calculation first. Currently I pause calculation with this method:

and just send the flag as YES or NO. However now I need to be able to wait for the calculation to have actually paused before continuing. So I have added a calculationDidPause delegate method that gets called once each time pause is requested and calculation ends. The -calculate methods looks like this now:

My code for encoding data in MyDocument looks like this:

I save only the things I need to save. The rest I can recreate when I load the data again. The code checks that the document type being requested is the type that I know how to encode. Then it uses a keyed archiver to archive everything into an NSData object and returns that. My code to read the data back looks like this:

I unarchive everything and then deal with the machine state and the interface. To make this work I had to add accessors for the first three. That takes care of disposing of the old objects and retaining the new objects and keeps this code simple.
I try to run the app without choosing anything and it writes a document and crashes. I wonder if there are nils in there I have to take care of? The document written is a binary plist so I can use Property List Editor to examine it. Data was written down to and including BTorderChoices. It doesn't matter where in the calculation I save, it always crashes.

My crash was an easy find. I'm learning that mysterious crashes mean that I have released an autoreleased object. The fix was to change my allocation of data to this explicit code:

And now it saves documents! I haven't added the code to pause first yet, and there are several other things wrong with the picture. If I load a saved document I see a problem: The view state is wrong: it thinks it is the Initial state even though I save the document in the Completed state:

Another thing wrong is that the icon is plain, as you can see in the title bar. No flower. So I need to fix the following:
1. Pause the calculation before saving
2. Fix the view state. This probably means making sure bindings know about the changes
3. Find out why no flower icon. If I do a Get Info on the document is does not know about my app being the program to open it with. This may be a Finder caching problem, not mine at all.
Reading and googling tells me that (3) is likely either a Finder cache problem, or a problem with the UTI. Get rid of the UTI or log out/log in and it might come back. So I got rid of the UTI and my icon appeared when I saved a new one.
Solving (2) required that I set up my view state not at load time, but after the NIB is set up:

I test for a nil machineState because if I am not loading from a file (starting the program for instance) it is nil. My -awakeFromNib code should probably be here as well.
Completed and Initial documents load and work fine:

Base chosen and Order chosen work too, allowing me to continue where I left off:

But paused documents are not OK. The state is correct, but the progress bar is at zero. And pressing resume doesn't do anything.

I know why pressing Resume doesn't do anything. That's a program structure problem. But the progress bar is stranger. I tried adding [self setProgress:[bagelturfNumberFactory progress]] to the -windowControllerDidLoadNib code, but that had no effect. The instance of BTBagelturfNumberFactory that is sent the -progress message has its variables set to defaults, not the values that I see read in -initWithCoder. That's a clue, since that is done in -awakeFromNib. Adding some logging messages reveals that -awakeFromNib is being called after the document is loaded and before -windowControllerDidLoadNib:

Since I set up my bagelturfNumberFactory in -awakeFromNib, this causes the problem. Opening a new blank document gives me this:

So clearly my program structure is wrong and everything in -awakeFromNib has to go into -windowControllerDidLoadNib. There may be some other changes needed as well so that the logic is correct.

When a document is loaded from a file it appears that -awakeFromNib is called, then -readDataOfType, and then -windowControllerDidLoadNib is called. I need no move all my initialization code from -awakeFromNib into -windowControllerDidLoadNib.
I moved the state array set up into -init. This only has to be done once. I also removed the set up of the Found... string since I now do that with bindings.

Here is my new -windowControllerDidLoadNib code:

I check to see if the setup has occurred already. If it has then I skip the initialization. Otherwise I do everything. The last thing I do is to update the view. And now it seems to work:

I paused the calculation and saved the document as Paused, then closed it and reopened it. The progress bar is set up now. But of course Resume does not work. And Reset does not work either since they both assume that calculations are running.
Another small change I have made is to add this code everywhere that the document was changed, either by the user or by calculation occurring:

This tells the document controller that the document has changed. That make it set the dot in the red close button on the window and prompt for saving when you attempt to close a changed document without saving.
Next, I have to rearrange the calculation code so that it is possible to resume calculations and add the code to pause calculation before a save.

Menu Clean Up
At the moment my app does not get the action that the Save menu item is linked to because I have not made that connection in IB. The application controller gets it instead and handles calling my -dataOfType method. By the time control gets to that method, the save dialog box has been used and the save should occur with no delay. Meanwhile, calculations could still be occurring. So if the state is Calculating, I have to request a pause. Either a pause is granted and -calculationDidPause is called, or the calculation completed and -calculationDidEnd is called.
This is getting complicated. Either way I cannot return from the -dataOfType method without some data, so that method has to wait for calculating to pause or finish completely, then gather data, then return.
Thinking about this and the way my program is structured I have come to the conclusion that it will need restructuring in some way to make this work. That implies that I have not designed my objects and their relationships correctly. This is trivially true since I have grown this organically and blundered about as I leaned more of what OO is about.
So my fix is to remove the feature -- if it's good enough for Microsoft, then it's good enough for me.
Now the problem is to disable the Save and Save As... menu items if in the Calculating state. All the other states are OK. I need to turn my attention to the menus anyway: they contain default entries, and I haven't cleaned them up yet.
Running through the menus, I find the following:

About NewApplication needs to be changed. If I select it I get the following:

The text for this is in credits.rtf in my project, so that is easy to fix. It's an RTF, so I should be able to put a description of the program in there with pictures and styled text. Not sure how I change the copyright notice. I don't see a NIB for this window.
I can do without the Services... menu also, since none of them are usable. And I have no prefs.
The File menu looks like this:

I need to control the Save and Save As... so that they are disabled in the Calculating state, but enabled according to regular rules in all other cases. Also I have no Print functions, so those will go.
On the Edit menu, Undo and Redo need to do, and I may have to turn off the undo manager somewhere in my app. In fact the whole menu can go. I support none of this.

The Window menu is fine as it is:

On the Help menu I need to change the menu item text and have it so that it brings up the About box.

The inspector in IB shows me how things are currently connected. The BTNumbers->About BTNumbers menu item shows this:

and the Help->BTNumbers help shows this:

So it looks like I can override -showHelp in MyDocument and redirect that to -orderFrontStandardAboutPanel. The Save menu item looks like this:

Next I have to figure out how to enable/disable menu items.

The Apple docs tell me how to enable and disable menu items: NSMenu updates every menu item whenever a user event occurs. A menu item is enabled if NSMenu can find an appropriate object that responds to the menu item’s action. If you want a menu item to remain disabled even though an object responds to the menu item’s action, define a validateMenuItem: method for that object.
So here is my code:

I used IB to set the Tag value for the Save and Save As menu items to 1000. That way I know if those items have been selected without doing any complicated work. Anything I don't understand I send to super. Otherwise I apply the rule that I cannot be calculating if I am to save. After I did this I also removed the Open Recent menu item and tagged the Open, Close and Revert items with 1000 as well.

I discovered two problems with my approach of disabling the menu items to prevent the user from doing things that do not work (ie I cannot figure how to code without a rewrite): 1) many of the menu items I disabled are not getting disabled, and 2) quitting of course lets the user save, and I cannot prevent the user from quitting the app!
So my solution to this is to ignore it for now and solve a different problem: getting the About box right. It looks like this by default:

The text comes from credits.rtf, a file listed in the Resources folder in XCode. I removed that and replaced it with my own credits.rtfd file -- one with an image. The code that brings up the credits looks for several file extensions: .rtf, .rtfd, .html in turn. The copyright message is in InfoPlist.strings, so that is easily edited.

I edited the text in TextEdit and pasted in a graphic with the equation:

I created that using Grapher and took a screen shot. The 1.0 version number comes from the target information Properties pane. I also included a web link in the text using TextEdit's Add Link feature:

Click and it takes you to the page by opening Safari. Simple and no coding needed.
My app still will not continue if you open a document that was saved in a paused state and click Resume. I have to do some coding to fix that. That's the next step.

The code that starts calculation in BTBagelturfNumberFactory looks like this:

Since loading a document sets up many of these parameters, all of this code is not needed: order, base, value, rangesize, testable, start, calculationComplete, and digits are set up. The last five lines are all that is needed. So I change the code like this:

and have the Start/Pause button click do this:

Now this will spawn a new thread each time I resume, but there is no other way to get calculations going if the document has been loaded. More evidence that my program structure is bad. I really need to have the calculating thread terminate on each pause, but have a way of getting its state such that I can reload the state and start calculating again. That would actually solve the other problem I have of pausing before saving and knowing when the pause has taken effect. Do away with pausing, at least internally and make pause/resume a save state/quit and reload state/start action.
I try this code and nothing happens when I click Resume. Debugging reveals that the client instance variable is nil: no delegate set up. The error was a simple one: I had not reestablished the delegate link between the archived bagelturfNumberFactory and self. So -readFromData:ofType:error needed modifying to look like this at the end:

And hey presto it works. Calculation is resumed and finishes.

Help will be simple: bring up the same dialog as About does. So, in IB look at where About is connected to by bringing up the inspector and clicking on the About menu item: it's connected to -orderFrontStandardAboutPanel in File's Owner (NSApplication). Disconnect the Help item and control-drag from BTNumbers Help to File's Owner and connect to orderFrontStandardAboutPanel.
It works.

The problem with pause and resume is that it is never going to work they way I want it to. I need to redo the code so that the only actions are Start and Stop. Starting either indicates that it must start from the beginning or that it must resume. Stopping always calls a delegate to say that it did stop. Implementing pause/resume means stopping and then starting. The interface to this part of BTBagelturfNumberFactory now looks like this:

and the delegate methods are these:

DidStart and DidStop methods are always called as balanced pairs. So my -calculate method now looks like this. Much simpler.

I count calls to Stop and balance each one with a call to didStop. The lock is still there. This pushes management of start/stop/pause/abort to the delegate method. When didStop is called, the delegate has to know why it was called: was it aborting or just pausing?
-startCalculationWithRangeSize:fromBeginning and -stopCalculation look like this:

Next I have to modify MyDocument to handle start/stop/abort/resume and track state there.

I edited MyDocument to work with the changes in BTBagelturfNumberFactory. I had to add two state flags:

These are set before -stopCalculation is called and examined in -calculationDidStop. The Start/Pause button click action now looks like this:

The state machine is manipulated as before, but now flags are set and the new methods are used. The -calculationDidStart method is unchanged, but the -calculationDidStop method now looks at the flags and acts appropriately:

Nothing else needed changing. Except the BTBagelturfNumberFactory -calculate method. That was buggy. Here is the new version:

I redid the loop to make sure that -stopCalculation was called if the calculation completed. It also fixes a problem where calculationStop was getting to -1 and going down from there -- forever.
Now my hope is that I can add automatic pausing so that when the calculation is saved (or the user quits and opts to save) it can be paused before it is written to disk. The previous code had foxed me on that, but I think that it will work this time with the addition of more state flags.

It appears that I need to implement an NSConditionLock to coordinate the action of the two threads when the user saves the document. NSConditionLock allows me to have the main thread wait on the lock and the worker thread set the lock to a specific condition that unlocks the lock. So the logic is to have the worker thread set the condition to one state when it is running and the other state when it exits. The code that needs to know that the worker thread has exited waits on the lock. If the condition is true or becomes true, then execution will continue, otherwise it will block.
I add a new instance variable to MyDocument: calculatingLock.

It will have a value of YES if calculating and NO if not. I initialize it in my -init method like so:

and release it in the -dealloc of course. Now in the -dataOfType:error method I add the following code to pause the calculation and wait on the lock:

At the end of -calculationDidStop I add this code to update the lock state:

and -calculationDidStart looks like this:

I try this and I get a deadlock: the lock in -dataOfType:error never has the right condition. The reason, I realize, is that my -calculationDidStop and -calculationDidStart methods are called on the main thread: so that thread waits for itself.
This means that I will have to move the code into BTBagelturfNumberFactory or have some method in MyDocument that is called by the calculation thread directly rather than through execution on the main thread.

Let's try another tack. Synchronous methods that are run on the main thread are very nice for GUI work and anything that doesn't want to have locks all over the place, but this situation is different: I do want asynchronicity here. I want to wait on a NSConditionLock and be woken when the condition is satisfied by the other thread. Attempting this synchronously will never work because a thread cannot unlock itself.
I've added two new delegate methods:

The two asynchronous ones will be called on the worker thread. Here is the new -clientCalculationDidStart method:

It makes the async call first, then the sync call. I modified other parts of the code to include these new symbols.
I tried all this and it is still not working. It hangs up on the calculatingLock waiting for condition NO. The log looks like this:

Interestingly the asyncCalculationDidStop message is never output. If I comment out the wait for the lock I get this:

Parts of it are mixed up. "Paused" comes before the asyncCalculationDidStop. So I am suspicious that there is more going on here than meets to eye. Could it be the logging that causes the problem? Here is the code in -dataOfType:error:

One more thing I can try is to make the lock static. I have seen examples that do this, so maybe that makes a difference? If I do that then I can do away with the extra delegate methods.

Another try. I'm now pretty well convinced that polling is the only way to go. I posted some questions to the Cocoa list and had some replies along the lines of "don't do it the way you are doing it" and "I had crazy trouble too". One person found that NSConditionLock worked as expected only when used with a static. Looking at code on the net confirms that this is the way it is done. That's no good to me, unfortunately because my calculation is in another class and another thread.
So polling it is. I'll add a sleep inside a loop and call a new method on bagelturfNumberFactory that tells me if calculation is ongoing:

I already take note of if the thread has ended, so this works as the calculating flag with the state flipped. My code to poll looks like this:

I sleep 0.1 second each time the calculation is found to be still calculating. And guess what? It still fails!

Now I think the problem is connected with *where* I am doing this, not *how*. What if -dateOfType:error is called in a context that does not allow any other threads to run? That would explain what I am seeing and how nothing works.
I changed -isCalculating to look like this:

It always claims to not be calculating. Now it does this:

Ignoring the Complete state at the end (why does it do that?), it is very odd that the log messages come with calculationDidStop after the machine state has been saved. I really think there is some blocking going on here behind the scenes.

I finally gave up and put a delay in the -dataOfType:error code after I requested that calculation stops. Not sure it is doing any good.
So now I turn my attention to saving the Bagelturf numbers that have been found as a text file. I modified the target information to include a text type (click Targets, select BTNumbers, click Info, then Properties tab):

I listed "Text" as Name, "txt" as Extensions, "text" as OS Types, and "MyDocument" as Class. I selected Binary as the Store Type. Now when I use Save or Save As, I get a choice of document types:

and I can choose Bagelturf Number Document or Text. Nothing happens of course, since I didn't write any code to do that.
The format I will write the data out will be comma-separated with line endings. That way it can be imported easily. The Result and Decimal columns will be the two entries on each line. No clue how to code this yet, since -dataOfType:error needs to return NSData.

NSData is just a container for binary from what I can tell. It wraps anything into a form that can be handled as an object. So to write out plain text I have to fill it with the correct text encoding and line endings. NSString has -dataUsingEncoding that looks like it will do the trick. A small test to see if this works:

That writes a couple of lines to a file. If I open the file in TextEdit, it looks OK:

So I modify my code like this to write out the comma-separated values:

and sure enough, it works. Base 16, Order 5 gives 23 numbers that come out like this in TextEdit:


How do you choose the location of the document window when it opens? It appears that wherever you have the document window open in IB is where it appears when you run the app. I moved it to a better location than I had it. Subsequent windows cascade from the initial window location.
The Order and base pop-ups always go upwards since the Select string is at the bottom, put there by bindings. I could not figure out how to fix that, so I reversed the order of the strings written into the pop-up. Now the useful Order and Base values are close to the Select string.
The results table has a large font size. How to change that? It turns out to be easy -- if you know how. Select the table and keep clicking until the NSTableView is selected. Now hit Command-T and select the font size from the pop-up. I selected Small System Font.

I also changed the "Press Start" message to "Ready to Search" and "Calculating" to "Searching", used a small scroller, and adjusted the table widths:

The performance is a fraction of what it could be. That's because I use a simple algorithm that has no optimizations. The obvious change is to replace the power calculations with a look-up table. Another is to store differences in the look-up table so that moving from n to n+1 involves adjusting the total not recalculating from scratch. Left as an exercise for the reader.
That's it for that project. I didn't achieve all the things I tried to do, but I learned a great deal in the process, which is what it is all about.

My next project takes its name from the fact that it is going to do some number crunching. Its purpose in life is to calculate Bagelturf numbers, about which more later. It is also going to have a multiple document interface and use an NSTableView to display results. So I'm going to have to be able to understand threads, opening and saving documents, and all sorts of other things to make this work. Here is the spec:
So what are Bagelturf numbers anyway? Here is a definition:Create documents, each one of which is capable of allowing the user to enter parameters to calculate Bagelturf numbers. Provide controls for initating, pausing, and stopping calculation, and a table for displaying the results of the calculations. Allow the user to save and open documents in any state except active calculation. Show a progress bar that reflects the progress of the calculation.
So, in base 10, if 4567 were a Bagelturf number then 4^4+5^4+6^4+7^4 would equal 4567. It doesn't, but it is close: 4578. Obviously you can change the base to ones other than 10 to make it interesting, which is why I included it. Are there any Bagelurf numbers in existence? There are. How about 1634 and 912985153 (both base 10) ?Bagelturf Number of Degree D, Base B: A natural number N is expressed in base B as D significant digits. The leftmost digit cannot be a zero. N is a Bagelturf number if and only if the sum of the Dth powers of the digits equals N.
Set-Up and Designing The Interface
I've noticed that all my header files have that __MyCompanyName__ string in them. Like this:
How to change it? A quick Google reveals the answer. Go to the terminal and type "defaults write com.apple.xcode PBXCustomTemplateMacroDefinitions '{ORGANIZATIONNAME = "My New Company Name" ; }'" without the outer quotes. Done.
Since I am creating a document-based application this time around, I have to start with a different template, a Cocoa Document-based Application template. It creates a set of file similar to those I had on my previous projects, but now there is a default class present: MyDocument. And there are two nibs, MainMenu.nib and MyDocument.nib. From what I understand, the structure of the objects is slightly different too. Instead of the application object creating a window controller, loading a nib, etc., all of that is handed off to the document controller. The application manages the document objects.
There is a lot of information in an Apple document entitled, not surprisingly Document-Based Applications. A lot of information indeed. A document-based app is much more complicated than a simple app. I'll be tackling that later, but for now, I need a user interface. Here is my effort:

A new window appears with Select as the selected item for Order and Base so the user is prompted to select some numbers. The Reset and Start controls are dimmed and the calculation status (shown as Calculating) is hidden. The progress indicator is hidden too, and the table is blank. The found status at the bottom is hidden as well.
Once both Order and Base have been chosen, Start becomes active. Clicking Start initiates calculations and the progress indicator and calculation status of Calculating becomes visible. The found status says Found 0 Bagelturf Numbers. The Start button turns into a Pause button, and Reset becomes active. The progress indicator moves left to right. The Order and Base poups are dimmed.
Clicking on Reset takes everything back to the start, as though a new window had been opened. I'll put up a dialog if any Bagelturf numbers have been found. Clicking on Pause halts calculation and changes the button to Resume. The status says Paused. Clicking Resume continues calculation and the button changes back to Pause. The status goes back to calculating.
As numbers are found, they are added to the table, on the left in the base set for the calculation, and on the right in decimal. The found message counts the number found. Once calculation is complete, Pause changes back to Start, dimmed. The calculation status changes to Complete. The Reset button is dimmed.
I am going to make this window resizable because in small bases and large digit counts, the results could get pretty long. That will involve dealing with springs and struts in IB. The size panel in IB's inspector lets me set up a minimum size:

I don't think I have to change anything else. New windows will be autopositioned.
if I "run" the interface in IB, I can play with the size and see what happens. This happens:

Not so pretty. I need to make the table stretch, but do other things for the other elements. The pop-ups should remain central at the top; the Reset and Start buttons should stay at the edges; the lines and the progress bar should stretch; the status and found messages should stick to the left edge. Everything should stick to the top except the found message.
Setting the springs just takes a little experimentation. Command-R in IB runs the interface and lets me resize the window and check out its behavior. Command-Q restores normal operation. There are a couple of problems remaining thought:

The static text Order and the popup are getting separated as the window stretches. And the other problem is that the Result column of the table does not share the new width with the decimal column. Ideally the decimal column would remain static (since the program can only handle numbers up to 2 billion since I will use 32-bit ints) and the Result column stretch.
The setting for the table sizing applies to the NSScrollView that encloses the table:

By clicking inside the table and onto the Decimal column header I can drill down to the column itself (an NSTableColumn object) and then I get what I am looking for:

I'll set the minimum and maximum to 100 for the Decimal column and adjust it if necessary later. I'll leave the Results column alone. Rats. It doesn't stick to the right side and stretch the Results column. I will probably have to do that in code.
The cure for the stretching space between the static code text and the popups is to use a box. Select all four elements and go to Layout->Make Subviews Of -> Box. Then make the box invisible, remove the title, and set its springs. Now that is fixed.

Here are the settings for the box that encloses the pop-ups:

Next: figure out how I am going to communicate with all of this. Outlet/action? Bindings? I'll have to be careful with the names too, since the buttons change their action.
Thinking About High Level Design
I've been thinking about the high level design of this program. It's not as simple as the others I have tried, so I'll actually have to think about its structure and do a little planning.
First though, I found a fix for the table column problem. I could not make the rightmost column stay the same width while the leftmost scaled with the window. I was looking in the wrong place. Double-clicking carefully on the table gets me to the NSTableView (not the NSScrollView or the NSTableColumn). The I adjusted the settings as shown.

And now it works. Note the resizing mode setting. I also turned off the horizontal scroll bar: stretch the window if you needs to see more.
Reading through the list of what happens when various interface items are clicked made me start to think about how to implement all this. It looks like a lot of code, spread all over the place. Not a good design. But it can be broken down into a set of distinct states and connected together in a state diagram. Still a lot of code, but this time table-driven, and all the complexity in one place. Then I started reading about swapping nibs to get different interfaces. Interesting, but complicated. Finally I hit on another way to go: use a tabless tab view.
If I create a tab view and use the Inspector to set it up, I can get rid of the background and tabs completely. Now by pasting my interface onto each page and editing I can set up everything I need for the different states. This drives some of the interface for me. I can channel all of the actions for a single control on all the tabs into a single method and give the tags appropriate values (no need to differentiate between them). The table and the Found status can be left off the tab view, since the table does not change, and the Found status has to be programmed anyway. Also the pop-ups don't change except for being disabled as I move out of the initial state and enabled when reset.
This leaves me with the lines (which don't change), the Calculating status which is static except for state changes, the progress bar, and the buttons. Now I'm thinking this is getting messy too. The tab views will be hard to manage if I want to make changes, and I may end up with a lot of outlets.
One thing is sure though, I want to have a separate object handling this view and to control it with state messages from my custom document controller. I will need methods to do a range of things too, including getting the pop-up settings, setting the progress bar, reacting to buttons, and filling the table with results.
So I create the BTDocViewController in IB from the Class menu and set it up. I can use bindings to control the pop-ups and the table. This may save a lot of coding, even though I don't fully understand bindings yet. I can bind to the buttons too. The bindings include title, action, enable, etc. Here are the available bindings for the Start button:

By hooking these up appropriately to BTDocViewController I can control and react to the buttons.
Another part of the high level design is going to be concerned with doing the calculation of Bagelturf numbers. Initially I will want to do this on the main thread, then, as an exercise in confusion, move the calculation to a separate thread so that the interface remains alive. So I will need an object for the calculation. Let's call that BTNumberCalculator. Start, pause, and reset can, I hope, be implemented via the object that controls the thread. But I will still need to perform progress bar updates, send initial values, and get back bagelturf numbers as they are calculated. My choices here are limited, since much of Cocoa is not thread-safe. At least the data I need to pass is small.
Setting Up The View Controller
I've decided that some interface elements will need actions so that I can act on them when they are changed. I don't think I can do the things I want to do using bindings because bindings only tie data values together. The Order, Base, Reset, and Start buttons will all need actions, so I set those up. Select the custom controller class in IB:

and use the Inspector's Attributes pane to set the actions:

These actions will need methods in the BTDocViewController class, so I can generate those in IB by using Class->Generate Files and accepting the defaults. For the other interface elements I will use bindings. That's probably not the best choice in all cases, but I am eager to learn and I think that I understand them now.
So lets design the state machine that the view controller will run. I count five states and eight things that need changing:

I will put the implementation of the states into the BTDocViewController. The interface to that controller will be the new state. That leaves the problem of how the BTDocViewController object tells the MyDocument controller that something needs doing, such as calculation starting or stopping, or communicating status, such as Complete. Maybe I can give my controller a delegate and make MyDocument a delegate?
The states transitions are pretty simple, as below. Go to the state in the table from the state in the heading when the lefthand action occurs:

There will be some additional state involved in deciding whether Order and Base have both been clicked, and that state will be reset by a transition to the Initial state. In addition, since the range of the numbers that can be calculated is limited, not all numbers will show up in the pop-ups. If the Base is 36, then any order larger than 5 will overflow 32-bit signed arithmetic, for instance. But I do not want my view objects needing to know anything about the implementation of the math, so that logic will have to be encapsulated in my calculation object. In that way I can improve the number range with no changes to the other objects. So I create a new class in XCode called BTCalculationEngine and set it up with two empty methods:

I will fill the methods in later (when I know how they should work!). For initial testing I will put some static arrays in there. So here is my skeleton BTDocViewController interface:

And the implementation:

Looking At View States
I missed a state transition: the one that includes the calculation finishing. The correct transition table is:

I also realized that the calculation engine methods legalBaseChoice:for Order and legalOrderChoice:for base should be class methods. Since they are just utility functions not tied to any particular instance.
Now to coding the interface to match the state table. As I think about coding this I can see that my states are all wrong. A alternative way of handling the states is to simply use NSStrings and encode the table as a NSDictionary keyed by state string containing NSDictionaries of instance variable values keyed by name. Now when sent a message to change the state I can look up the state and iterate through the selected dictionary setting the instance variables.
Or maybe I can get the bindings to do all of this for me. If I bind the dictionary selection to the state string, then I should be able to select the correct item in the dictionary automatically. Then maybe I can bind the individual display elements to the dictionary selection using a key path of some sort.
A Mysterious Crash
I coded the state table into a dictionary of arrays and created accessors for all of the interface elements to be bound to. Then I wrote code to look up the state string as a key in the dictionary and access the array elements by index to know what state to set the view elements to.
Only it doesn't work because on the second state change the application crashes. I know it is a memory retain/release problem, but for now I have run out of time debugging it. I'm pretty sure it is an autoreleased object getting released when I don't want it to be.
Crash Resolved
It was a simple memory retain/release error. I'm still thinking in terms of static variables, when in this object-oriented world there are very few. I had written my -awakeFromNib like this:

but had omitted the [machineStateIEs retain] line. So the first -changeViewStateTo worked, but the second had no object since the autoreleased NSDictionary had been released by the run loop. I also added a balancing [machineStateIEs release] in -dalloc of course.
The Found... strings will be fixed later since I will use those as formatting strings for the number found.
Updating the State and Order/Base Calculations
I am updating the state from the dictionary of arrays with this code. Each item that is a NSString is just passed to the accessor. The others test the length of the string and pass YES if non-zero. Another way I could do this is to store the YES/NO values as strings in my object and have a value transformer that converts "YES" to YES and anything else to NO.

Next I want to be able to have the code correctly set up the pop-ups for Order and Base. I will do that in -awakeFromNib and will call the class methods legalBaseChoicesForOrder and legalOrderChoicesForBase. But first I have to code those.They are necessary since the calculation engine has a limit on the largest number it can handle. I make these class methods because they are not associated with any particular object: they reflect the ability of the entire class as implemented.
Since I am using 32-bit ints, the largest number I can represent is 2 to the power 31 minus 1, about 2 billion. With no Base defined, Order (the number of digits) can be 2 to 31 since the smallest Base is 2. So if Order = 0, Base = 2 to 31. With no Order defined, Base can be anything from 2 (binary) to whatever I can represent, say 36 (0..9 and A..Z).
So I define some symbols:

and then use them in this code that calculates what is legal:

I don't have enough code to test this yet. Although choices is a mutable array, it lets me return it as an immutable array. I assume it is doing the Right Thing for me here, whatever that is. I autoreleased the choices array so that the receiver can retain if needed.
I don't have any outlets between the view controller and the pop-ups yet. I am hoping that I can figure out how to make bindings work so that I just update arrays and the content of the pop-up follows. That is the next task.
Filling The PopUp Menus
I created an object to do the calculations for this application, but have realized that I have not thought out the interface to it carefully enough. Currently the two methods I have written return NSNumber objects for the valid values -- not good. Since only BTCalculationEngine knows the size of the numbers and how to express them to the user, I should have the complete interface be NSString objects. This also allows the calculation engine deal with localization, if I wished to add that.
So I replace my array building loop with this:

which will fill the array with strings containing the values. I can use that to populate the pop-up directly:
Since setBaseChoices retains the new object, the autoreleased array returned by BTCalculatuonEngine should stay allocated. That in turn will retain the strings. I set up bindings for Order and base pop-ups as below:

I had hoped that setting the No Selection Placeholder would display "Select" initially, but that did not happen. I suspect that this is because I have not bound the control to an array controller (content). The fix will be to add the string "Select" into the array and remove it when the first choice is made.
So what happens? Both pop-ups display correctly, showing a list of numbers as calculated. So far so good., However after I set the pop-up actions to -baseChosen:sender and -orderChosen;sender and selected new numbers, I got a crash. The action methods are never called.
The error was a simple one: memory allocation again. The autorelease I was adding to the array of strings was bogus: it is already autoreleased, so no need. I was over releasing it. Here is the corrected code snippet:
Reorganization and Working Pop-Ups
I reorganized my code. My BTDocViewController was serving no useful purpose, so I moved its content over to the MyDocument object. I can understand the value of encapsulating functionality inside custom view objects, but what I was doing -- delegating some code to another controller -- was not worth the effort. So now I have two objects: MyDocument which is my controller, and BTCalculationEngine which is my model.
I also threw out all my code for handling the "Select" pop-up string and replaced it with bindings. I had made a design blunder that caused me to do this: the Select string was being added in one place (the model) and removed in another (the controller). What I replaced it with is illustrated by the action code for a Base choice:

This extracts the chosen Base string, sends it to the calc engine to get an array of valid Order strings, sets the chosen Order to the one stored in the model, and sets the Base string in the model. The setChosenOrder message is needed because updating the string array causes the bindings to select the first element. The rest of the work is done by bindings. I set up the bindings for the Order pop-up like this:

orderChoices is the NSArray of NSStrings generated by the model. chosenOrder is the Order chosen by the user by clicking the pop-up. By binding the selectedValue of the pop-up to a variable in my controller I can make it automatically present and dismiss the "Select" string:

See the Null Placeholder box at the bottom. When the Reset button is pressed I run this code:

This sets the chosenOrder and chosenBase to nil and that, via the bindings makes the Select placeholder appear again. Note that my interface with the calculation engine is now completely NSStrings. Passing a nil NSString generates all the possible orders or bases.
My document instance variables now look like this:

I can actually use an NSArray instead of a NSMutableArray now I have stopped trying to modify the array myself. I also has to create an instance of the calculation engine. I did that in -awakeFromNib and released it in -dealloc.
So what doesn't work? The only problem I have is that the pop-up, when displaying the Select string has all the numbers above it, not below as you would expect. I don't know how to fix that. An improvement I can make is to bind the controller's chosenBase and chosenOrder to the model's baseString and orderString. I will have to do that programmatically because IB is not there to help me, but once done, the view change will update the model with no code needed in the controller since the two bindings will propagate the change through. Maybe if I can do that, then I can make it work for the sting arrays as well.
Implementing Value Transformers
More reorganization and changes. I have simplified the use of my state table by using value transformers in the bindings and converting all my BOOL variables to NSStrings. I have created two value transformers: StringToBoolTransformer and StringToColorTransformer. Here is the latter. The interface code looks like this:

And the implementation code like this:

This returns a color depending on whether a string starting with "Y" or "y" is passed. So since my table of states has strings with "Y" when I want something enabled, I can set up the bindings in IB like this:

This is bound to the static text that says Order and Base. Now when the pop-up is disabled, the text goes grey. I did a similar thing with the Start/Pause button, binding its enabled state to a string via the other value transformer. So now my code for updating the state looks like this:

I simply pass the strings through. To set up the value transformers I had to add this method to MyDocument:

+initialize is called once for each class. This registers the transformers with the NSValueTransformer class and makes them available to bindings.
Bagelturf Number Object and Calculation
I created an object for my Bagelturf numbers, BTBagelturfNumber, and in doing so reorganized a great deal. Why do I need an object for my numbers? I need to keep the calculation, and storage of them separate from the view and the model since I want the implementation to be completely independent. Here is the interface to BTbagelturfNumber:

All you can do is initialize one with a decimal value string and a base string and then read out the decimal value and a representation of that value in the base. This will allow me to show the numbers in the table without having to manipulate any math and without knowing anything about what the number is or how big it is. I will probably have to make this object conform to NSCoding and NSCopying, and implement isEqual to make it work with everything else I want to do.
The implementation is below (untested!). I omitted the accessor code:

I copy the valuestring straight into the object. I believe that retains for me, so I don't have to add one. Then I start with an empty mutable string (nativerepresentation) and add ASCII characters to it, shifting right, so that the least significant digit is at the right (highest index in string). Then I assign the finished string and retain it in my object. The dealloc releases the strings.
The next thing I changed is the BTCalculationEngine. The name I gave it is a very functionally-oriented name, not object-oriented, so I changed it and created a set of methods for it. I now call it BTBagelturfNumberFactory, since that is what it is: a factory for creating BTBagelturfNumber objects. Here is the interface:

The class methods are there, as before. The factory is created with the Order and Base and deallocated when it is no longer needed. To tell it to do calculations, I added the method -generateInNextRangeOfSize. rangesize tells the engine how many numbers to test. Any Bagelturf numbers it finds are created as BTBagelturfNumber objects and returned in an array. Each time the method is called it starts from where it left off. I did it this way because it will let me break the calculation up into chunks -- I don't yet know how I am going to make the calculation run while keeping the interface alive. Passing rangesize of zero will let the calculation proceed to completion. The -progress and -complete methods allow me to query the factory object to see how far calculation has progressed (as a fraction of the possible numbers) and to find out whether it has exhausted the possible numbers.
I won't post the whole code here (it is long and not yet debugged), but here is the part where it creates a BTBagelturfNumber when it finds one:

I think I got the alloc/release right. I explicitly allocate the strings and then explicitly release them. I don't want to use the autorelease pool because I could be doing this many times as calculations proceed. The -initWithValue:andBase method does retain the strings.
Now the problem is how to run the calculations on multiple document windows, updating the progress bar, and the number found, while being alive to process clicks on the buttons.
I think what I need to do is to create the number factory on a new thread. That thread puts calls to -generateInNextRangeOfSize in a loop and adds a short delay to give the CPU time to keep the interface (on the main thread) active. It also tests to see if calculation is complete. If it is, it exits. I can use -performSelectorOnMainThread to update the array of results (and hence via bindings the table) and the progress bar.
One thing I am not sure about is how to implement Pause/Resume. One way may be to sample the state of the state machine. If it is Pause then don't do any more calculations and do sleep a while. If it is Calculating then continue as normal. if it is Initial then the reset button was pressed so exit.
By my reckoning I have three major items to complete: multithreaded operation, displaying results using bindings, and saving/restoring from disk (since this is a document-based app).
Results in The Table
I posted completely brain-dead code the other day, as I found out when I debugged it. Programming while tired. Here is the working version:

I tried to get results to show up in the table now my code is generating some. For the purposes of debugging I created a -calculate method and stuffed some code into it that ran the calculations 100 at a time and put the results in the bagelturfNumbersFound array:

For Base 10 and Order 7, that's seven digits, 9 million numbers, it processes the whole range in about five seconds. The code for searching is very naive and unoptimized, so probably a factor 10 speed up is easily possible. Then I hooked up the table to the array of results by doing this:
1. Drag a NSArrayController into the MyDocument nib.
2. Add nativeString and decimalString as attributes of the NSArrayController and change Object Class Name to NSMutableArray and select Automatically Prepares Content
3. Control drag from the NSArrayController to File's Owner and select the content outlet.
4. Selected the Result table column header and filled in the binding for value as Bind to: NSArrayController, Controller Key: arrangedObjects, Model Key Path: bagelturfNumbersFound.nativeString
5. Repeat for the Decimal column header with a different Model Key Path setting.
The result was interesting (and incorrect):

Clearly there is something I don't understand about binding array controllers and tables. If I repeat with a hex base, then the result column correctly shows hex, so at least that works. Somehow I am telling the table columns to put the entire array into one entry. So try again:
1. Drag an NSArrayController into the MyDocument.nib window
2. Add nativeString and decimalString as attributes of the NSArrayController and change Object Class Name to BTBagelturfNumber
3. Bind the contentArray of the NSArrayController to File's Owner (MyDocument), Model Key Path bagelturfNumbersFound
4. Select the Result table column header and fill in the binding for value as Bind to: NSArrayController, Controller Key: arranged Objects, Model Key Path: nativeString
5. Repeat for the Decimal column header with a different Model Key Path setting.
Nothing. I suspect that I am leaving something out, since I get no errors, but I cannot see what. The table columns are bound to the arrangedObjects and the array controller the contentArray. I have the correct object type set up. Maybe I have to provide accessors for my array -- but it is not a custom class, just an NSMutableArray.
Changing my update of the table to this code worked:

The problem was that I was bypassing KVO: nothing was being notified that the array contents had been updated, and so no table display. Here is what the final result looks like:

I don't get a progress bar when it is calculating, and the spinning pizza appears after a while, but I expected that: I'm not letting the interface update because the run loop isn't being run.
Another problem: the columns do not sort in the right order. They sort using alphabetic sorting instead of numeric sorting, so when I use other bases, this happens:

The "1" numbers are at the top. The Result column will not have this problem because it always has rows with the same number of characters.
Interface Clean Up
To implement the Found string, I used bindings again. I removed the binding that existed (value to a string in my controller) and set up a new binding like this:

This substitutes the count of lines specified in the model key path for %{value1}@ in the Display Pattern. This works:

but it has a flaw: if one number is found, it says Found 1 Bagelturf Numbers. The "s" is there. Also when none are found it would be nice if there was no string. I found I could implement that like this:

An array item is removable if there is at least one, so I invert that with the NSNegateBoolean value transformer and use that value to control the hidden attribute. I can change the string on the other binding to remove the plural by changing it to "Bagelturf Numbers Found:" But this has a problem. If I click away from any of the found numbers then the string is hidden, since canRemove needs at least one number selected. But this setting does work:

I simply use the fact that FALSE is zero and invert the @count.
I discovered that I can disable sorting on the table using a hint on http://homepage.mac.com/mmalc/CocoaExamples/controllers.html (Disabling sorting in a tableview).
Now I'd like to disable selection completely on the NSTableView. I don't want either the highlighting or any selection to be made. I found this comment: "You can disable selection by always returning NO for the tableView:shouldSelectRow: and "tableView:shouldSelectTableColumn: delegate methods." So in theory I can set up an outlet to the NSTableView, make self (MyDocument instance) the delegate, and implement those.
So in the MyDocument.nib file, click on File's Owner and select Classes tab. Add a new outlet called tableView of type NSTableView. Now go back to the Instances pane and control-drag from File's Owner to the table view. Click Connect and the outlet is connected. I still have to add the instance variable to MyDocument. That is done like this:
So in -awakeFromNib I can set MyDocument to be the table view delegate:
The delegate code looks like this:

And this works -- up to a point. It does prevent selecting the table, but when the table first is filled, there is a selected row. I guess I will have to do something to the array controller to prevent that. I had another go at the array controller attributes and came up with this:

This seems to work. Now the results look like this:

No selection border, no selected row, and the count in place. The next challenge is getting the calculation to take place in a separate thread.
A Fix For The Count Problem
I found an answer to my problem of how to change the text for the count of Bagelturf numbers depending on whether one was chosen or more: "1 Bagelturf Number Found" -> '2 Bagelturf Numbers Found".
The trick is to maintain an outlet to the array controller so that the number of items in the controlled array can be obtained. Write a method to return either an empty string or "s" depending on the number. Now create a display pattern that binds to the method and put that string into the display pattern in the appropriate place.
Here is my method. I didn't have to create a setter since it is never called:

I set up the disply patterns for the "Found" string like this:

Expanding the two display value items gives:

And this is how the result looks for one number found:

Threaded
I've now made my application run with a separate thread. And a crash. The search works all the way to the end and then crashes. Also there are some interface problems. This is not to be unexpected since I made the change without thinking about what is thread safe and is not and how the thread should communicate with the main thread. Here is a screen shot of it working:

I start the thread like this:
And implement the thread itself like this:

I have some code commented out that I thought might be needed. The sleep was not needed to keep the interface alive. Also I thought that the state change was causing the crash, so disabled that. The code tests 100,000 numbers and then does updates.
One way to handle the progress bar and other things is to do them from a method called by a timer. I can call the -progress method in the timer method and update the progress bar. But this may have the same thread problems that I have now. I'm pretty sure that the crash is coming from my deallocating something that is still in use. I have also not thought out how to implement the pause function or handle reset or completion.
Better Threading
If I limit the calculation to short spans, such as Base 10 Order 4, I get no crash. Base 10 Order 6 crashes. I also get this message:

indicating that this is definitely a memory allocation problem -- probably a double release. The crash report gives this:

It is my thread that is crashing, and it appears to be at the [pool release]. And I think I found and corrected the bug. The crash occurred much more often if I paused and resumed the calculation. So I looked at the NSDate code I had used and realized that it was releasing autoreleased object instances in an effort to prevent them from using up memory. This was fine until the autorelease mechanism did the releases. So the new code explicitly allocs and releases the NSDate object:

This checks to see if the state is Paused. If it is, then it sleeps the calculation thread. If not, it calculates.
I also have an overwriting problem. The count of numbers found is getting updated by bindings automatically and gets to look like this quite often:

So now I need to look carefully at how I update the array and the interface.
Thread Discussion
Getting things to run in separate threads seems to be a subject of much discussion and few simple answers. I posted a question in the Apple Cocoa list:

thinking that there should be a way to do things to threads. Create, start, control, destroy, the thread externally so that the thread contains only crunching code and is unaware of its environment, treating the thread like it was a nicely-bahaved object. I'm used to doing things that way with separate processes: fork it and send it signals or make it suspend or use locks to make sure that it does what you want. Kill it with a signal and have it take care of its own clean up. But no, it does not appear to work that way. Threads in Cocoa have to be wound closely with the main thread.
One approach posted by Ryan Britton used a flag called stopThread that was polled by the worker thread in its loop to abort the loop. It used an NSLock to lock access to critical sections of code so that the main and worker threads had exclusive access to data structures that were updated. And it also used the @synchronized directive to obtain exclusive access to a block of code. It used -willChangeValueForKey and -didChangeValueForKey so that bindings worked and it wrapped those in -performSelectorOnMainThread. No feature for pausing the worker thread.
Another post from Ben Haller suggested going behind the scenes and using PThreads (Posix threads). That would appear to simply bypass the interface provided by Cocoa and could be changed at any time.
J o a r suggested using NSConditionLock, a class similar to NSLock. This still requires a polling thread and won't do the quit of the thread, just the pause/resume. The suggestion to that was once it comes out of the lock have it decide whether to die or not.
Matt Holiday (who shamelessly copied my web site design) had this suggestion:

I like the idea of running my thread inside an object and having delegate methods. He suggests having delegate methods -didFinishRange and -didFinish so that I can perform clean up in my main thread. Again I like this. It is nicely objectified, something I had not done yet.
So my next task is to refactor the code so that I follow all the rules and apply locks where necessary.
Delegate Design
Since I need to embed my calculation in an object to make threading work better, the easiest thing to do is to use the BTBagelturfNumberFactory class and add new methods to it for controlling and monitoring the calculation. I'm going to implement a delegate that is called when certain things happen, and am going to ensure that I run all the GUI updates on the main thread and use locks in the right places.
Here is a stab at a new interface for BTBagelturfNumberFactory:

I have gotten rid of the -initWithOrder:andBase method. Instead there is a plain -init and a -setOrder:andBase method.
The delegate is set using -setDelegate and is stored as the client instance variable. There are two ways to start a calculation: -startCalculation just runs to completion; -startCalculationWithRangeSize just tests a range at a time. The calculation can be aborted with -abortCalculation and can be paused and unpaused with -pauseCalculation passing YES or NO.
The delegate methods are called according to what is going on. -calculationDidStart and -calculationDidEnd are called once only at the very start and the very end of calculation -- always -- irrespective of how calculation s started and ended. If the calculation is aborted then -calculationDidAbort is called once. If the calculation is carried out one range at a time, then before each range is calculated -calculationInRangeDidStart is called, and after the range is calculated -calculationInRangeDidEnd is called. The latter returns an array of BTBagelturf number objects if any were found.
All delegate methods are called on the main thread.
Initialization of BTBagelturfNumberFactory objects now looks like this:

I will be adding some more code to -init later when I implement the delegate methods, but for the time beeing it just sets a few instance variables to default and safe values. -setOrderAndBase is very simple:

Further set up of the calculation will only be done when it is actually started. I also added this code to the end of MyDocument's -awakeFromNib:

Now I am creating the factory and the result array right at the beginning, rather than waiting for the user to press Start. The -dealloc method has been changes as well:

My -calculate method (with heavy editing) will move into the BTBagelturfNumberFactory class too.
Delegate Methods
To call my delegate as things happen, I have made a pair of methods for each delegate method that look like this:

The first method is called by the calculation code. It calls the second one on the main thread to avoid any GUI update and other issues. The second one calls the delegate method if it exists. The code for clientCalculationInRange is a little different because there is a results array passed back.
The clientFlags value is set up in -setDelegate:

This prevents the tests happening very often and will also handle a changing delgate. Here is my new -calculate method, the one that is called on a separate thread:

I call the delegate at the appropriate places and check three flags: calculationAbort, calculationPaused, and calculationComplete. These are modified by -abortCalculation, -pauseCalculation, and -generateInNextRange respectively. Pausing inserts delays but keeps checking for aborts. Otherwise calculation is performed and the delegate informed at the start and end of each range if ranges are used.
Locks
There are some calling patterns that I want to make sure are always followed. For example, each call to -calculationDidStart should be matched one for one with -calculationDidEnd. To enforce this I will have to take a careful look at how the calls are invoked in the BTBagelturfNumberFactory class.
-calculationDidStart and -calculationDidEnd will always be paired, as it turns out, since the program flow enforces it. A harder pattern to enforce is that I want exactly one call to -calculationDidAbort to be made for each call to -abortCalculation. I need these two paired because I can start the abort at any time, but will have to wait until the calculation reaches a certain stage before I can do much else. The way to implement this restriction is through locking.
There are two cases that have to be covered: a) calculation is still in progress and will pass through a call to -calculationDidAbort in a while, and b) calculation has already ended, so an explicit call to -calculationDidAbort is needed.

I added a flag threadEnded. This is also manipulated in a locked section of code. My lock is an NSLock, set up in -awakeFromNib. The logic counts calls to -abortCalculation and if calculation has already ended, performs an immediate call to the delegate. The code at the end of -calculate now looks like this:

After control exits the loop for any reason, any count of calculationAbort is matched by a call to the delegate method. The threadEnded flag is set in the locked section so that it is clearly connected with the abort code. Strictly speaking it does not have to be inside, but if it is not the order in which it and the abort count are manipulated is important (and easily wrecked).
Debug debug debug. After making some corrections (mainly caused by moving so much code around) I have an app that works threaded and keeps the interface alive. The progress bar progresses, I can pause and resume, and I can abort by pressing Reset.
Here are the delegates I implemented in MyDocument:

-calculationDidEnd transitions to the Complete state if it was Calculating. The other alternative is that it was aborted and is now in the Initial state.

-calculationDidAbort resets everything and empties the results array. This lets the user start the calculation again. Bindings take care of parts of the interface update, such as the table contents. The button press should prompt the user with a "do you really want to do this" alert so that calculations are not lost immediately.

-calculationInRangeDidEnd updates the progress bar by calling the number factory to get it (a float) and then stores any results that were found in the range. The results store is wrapped so that the bindings are aware of the new data and the display is updated.
The other delegates are not implemented.
Reset Warning
Adding a warning to pressing the Reset button was pretty easy. I edited the Reset button click code so that it created a modal sheet for the window. The only hitch I hit is that informativeTextWithFormat cannot be nil: you have to use an empty NSString if you want it to be blank.

-beginSheetModalForWindow calls a delegate when the sheet is dismissed. You give it an object (self in this case) and a selector. In the -resetWarningSheetDidEnd code I simply test to see if the Reset button was pressed or not. This fits in well with the way that I have reorganized the program: I don't have to worry about what happens after I abort the calculation and I can abort from several places in my code with a simple call.
The way this is implemented, calculation continues while the sheet is up. This works fine. Here it is with the sheet:

Now I notice that when I pause the calculation, the program still uses CPU: about 3-4%. I think I can lower this by doing two things: stopping the animation of the progress bar, and changing my polling pause into one that stops on a lock until unpaused.
I tried that: no luck. You can't stop a determinate progress bar from animating. And adding a lock didn't save any CPU. It's the animated progress bar that takes all the CPU.
Make Some Icons
The next step is to be able to save and load my Bagelturf number documents. I want to be able to do a number of things:
1. Save and load a document that has finished calculating
2. Save and load a document that is in the middle of calculating (it pauses first)
3. Save Bagelturf number data as raw ASCII to a .txt file
4. Warn the user to save if they quit the application with unsaved data
5. Have the red close dot be marked when unsaved data is present
I'm also going to set up an application icon, a document icon, and clean up the menus so that all the extraneous items are removed and what is left is implemented.
First I'll set up an application icon and a document icon. For the app icon I start with a photo and use Photoshop to remove the sky, then drop the scaled result into Icon Composer. Icon Composer is a utility that is supplied with the developer tools. Then I scale and repeat to make the other sizes, dragging and dropping PSD files each time. The alpha channel is included in the icon and shown as red here:

Icon composer saves this as a .icns file. For the document icon I want to add the flower to a plain document icon. This is trickier and requires more specialized tools. I downloaded Iconographer and used it to get the icon from a plain text file.

Now I can export the 128 pixel thumbnail as a .PSD file and open in Photoshop, add a small version of the flower icon, and reimport it into Iconographer so:

And save as a .icns file. Then open in Icon Composer and drag the big icon onto the small icons to generate them. I know there are easier ways than this, Folder Icon X is one, but this is a quick and dirty exercise to get me something to use for my app.

So I have two .icns files: Flowerdoc.icns and Flowericon.icns for use in my app.
Adding Icons To The Project
For my application to use the icons I created, I have to put them in the resources folder, English.lproj and tell the app that they are there.

Selecting the BTNumbers target in my project and opening the info window (click the blue "i" in the project window) and selecting Properties gets me this:

I have to edit this. Clicking on the purple ? brings up the relevant docs.. I have to change the identifier. I'll use com.bagelturf.BTNumbers. I don't need a Creator since I don't open any standard file types and don't want to appear in Open With lists for them. I add the flower icon file name and leave the class and nib names alone.
The document types I need to edit. I want to be able to write plain .txt files and have a binary format of my own. The first one I will create is one for Bagelturf number files. Document type is "Bagelturf Number Document". The UTI (Uniform Type Identifier) is specific to my app and document, so I can use my own: "com.bagelturf.btnumbers". Extensions I will make "bgtn". For a MIME type I will use "application/octet-stream" since I am going to be storing binary data. For OS Types I will use "bgtn" again. This is there so that files stored with no extension can be associated with the app. The Class is MyDocument. The Icon File is Flowerdoc.icns. Storage is Binary. Role is Editor, since I can open and change an close these documents. And I uncheck the Package box.
I am not certain that I need to create a Document Type for a plain text file since I will only be writing that.
I also have to add the icon files to my project by dragging them onto the Resources folder in the project window.
Here is the Properties pane set up. It is very wide, but not stretched out here:

And when I run my app, it does indeed have the flower icon.
The application name is actually set on the Build pane. I trid to set that to Crunchie, but then my app has no menu bar. If I change all the other occurrences of BTNumbers to Cruchie I still have the problem. Wierd. If I add a new executable and call that Crunchie, then I get an error No Executable Present At Path. The executable information window lets me set up a path, but I have no idea what it should be. I just put Crunchie.app into the window.
I eventually tried the full path: finding the Crunchie executable with Spotlight and then navigating to it:

This lets me run the program in XCode as "Crunchie", but it has no icon in the dock, and no menu bar.
Saving Data
There appear to be a wide array of choices as to how I save and load data. The way the document template was created, I have two methods already implemented for me waiting to be filled in:

If I set a breakpoint on -dataRepresentationOfType, and use Save from the menu I can see "Bagelturf Number Document" as the type, and the save dialog has bgtn as the file extension. The text gives me some other options and the recommended ones are -dataOfType and -readDataOfType.
But my document doesn't really have any data as such. I actually want to save and load the instance variables of MyDocument since I want to be able to save the current state of the object (and the model object) in order to be able to pause calculation and resume it. So I need to use an NSCoder. The recommended way to go with Tiger is to use NSKeyedArchiver and NSKeyedUnarchiver. These let you assign keys to each piece of data that gets written out and read back the data by key name. It's like a persistent dictionary.
Encoding and Decoding My Objects
In order to save and load my document I have to be able to save and load the objects it contains. This means making my objects comply with the NSCoding protocol. Starting with BTBagelturfNumber, I amended the interface file to look like this:

This includes the -encodeWithCoder and -initWithCoder methods and also claims compliance via <NSCoding>. Tiger records class versions into keyed archives, so I will set that up for this class:

That sets the class version to 1. If the program is modified and the data I need to store changes, I can use the version number to know what data exists and how to use it. To actually code and decode my object I use these methods:

Since BTBagelturfNumber objects inherit from NSObject there are some changes to what you would expect. NSObject does not comply with the NSCoding protocol. The encoding and decoding of the two strings could happen in any order since they keys are used to reference the data. The decoder simply uses the accessor methods to set the new decoded values, both NSStrings.
More Encoding and Decoding
Now I have to do the same treatment for BTBagelturfNumberFactory. All the instance variables of this class that need saving are not objects, so the coder and decoder will have to be slightly different. One of them is a simple C array.

When the user selects Save from the menu then the document class will pause the calculation if necessary and then do the save. This will put the instance variables that are not saved into a known state. Here is the code for the encoder and decoder:

I have to convert the array of digits into something that can be coded, so I create an NSArray of NSStrings, each string being a representation of the int in the C array.
The next task is to make the MyDocument class save and load its contents.
Pause And Encode
Before I can save the data in my document I have to check to see if calculations are ongoing. If they are then I must pause the calculation first. Currently I pause calculation with this method:
and just send the flag as YES or NO. However now I need to be able to wait for the calculation to have actually paused before continuing. So I have added a calculationDidPause delegate method that gets called once each time pause is requested and calculation ends. The -calculate methods looks like this now:

My code for encoding data in MyDocument looks like this:

I save only the things I need to save. The rest I can recreate when I load the data again. The code checks that the document type being requested is the type that I know how to encode. Then it uses a keyed archiver to archive everything into an NSData object and returns that. My code to read the data back looks like this:

I unarchive everything and then deal with the machine state and the interface. To make this work I had to add accessors for the first three. That takes care of disposing of the old objects and retaining the new objects and keeps this code simple.
I try to run the app without choosing anything and it writes a document and crashes. I wonder if there are nils in there I have to take care of? The document written is a binary plist so I can use Property List Editor to examine it. Data was written down to and including BTorderChoices. It doesn't matter where in the calculation I save, it always crashes.
Document Loading Problems
My crash was an easy find. I'm learning that mysterious crashes mean that I have released an autoreleased object. The fix was to change my allocation of data to this explicit code:
And now it saves documents! I haven't added the code to pause first yet, and there are several other things wrong with the picture. If I load a saved document I see a problem: The view state is wrong: it thinks it is the Initial state even though I save the document in the Completed state:

Another thing wrong is that the icon is plain, as you can see in the title bar. No flower. So I need to fix the following:
1. Pause the calculation before saving
2. Fix the view state. This probably means making sure bindings know about the changes
3. Find out why no flower icon. If I do a Get Info on the document is does not know about my app being the program to open it with. This may be a Finder caching problem, not mine at all.
Reading and googling tells me that (3) is likely either a Finder cache problem, or a problem with the UTI. Get rid of the UTI or log out/log in and it might come back. So I got rid of the UTI and my icon appeared when I saved a new one.
Solving (2) required that I set up my view state not at load time, but after the NIB is set up:

I test for a nil machineState because if I am not loading from a file (starting the program for instance) it is nil. My -awakeFromNib code should probably be here as well.
Completed and Initial documents load and work fine:

Base chosen and Order chosen work too, allowing me to continue where I left off:

But paused documents are not OK. The state is correct, but the progress bar is at zero. And pressing resume doesn't do anything.

I know why pressing Resume doesn't do anything. That's a program structure problem. But the progress bar is stranger. I tried adding [self setProgress:[bagelturfNumberFactory progress]] to the -windowControllerDidLoadNib code, but that had no effect. The instance of BTBagelturfNumberFactory that is sent the -progress message has its variables set to defaults, not the values that I see read in -initWithCoder. That's a clue, since that is done in -awakeFromNib. Adding some logging messages reveals that -awakeFromNib is being called after the document is loaded and before -windowControllerDidLoadNib:

Since I set up my bagelturfNumberFactory in -awakeFromNib, this causes the problem. Opening a new blank document gives me this:

So clearly my program structure is wrong and everything in -awakeFromNib has to go into -windowControllerDidLoadNib. There may be some other changes needed as well so that the logic is correct.
Sorting Out Document Initialization
When a document is loaded from a file it appears that -awakeFromNib is called, then -readDataOfType, and then -windowControllerDidLoadNib is called. I need no move all my initialization code from -awakeFromNib into -windowControllerDidLoadNib.
I moved the state array set up into -init. This only has to be done once. I also removed the set up of the Found... string since I now do that with bindings.

Here is my new -windowControllerDidLoadNib code:

I check to see if the setup has occurred already. If it has then I skip the initialization. Otherwise I do everything. The last thing I do is to update the view. And now it seems to work:

I paused the calculation and saved the document as Paused, then closed it and reopened it. The progress bar is set up now. But of course Resume does not work. And Reset does not work either since they both assume that calculations are running.
Another small change I have made is to add this code everywhere that the document was changed, either by the user or by calculation occurring:
This tells the document controller that the document has changed. That make it set the dot in the red close button on the window and prompt for saving when you attempt to close a changed document without saving.
Next, I have to rearrange the calculation code so that it is possible to resume calculations and add the code to pause calculation before a save.
Menu Clean Up
At the moment my app does not get the action that the Save menu item is linked to because I have not made that connection in IB. The application controller gets it instead and handles calling my -dataOfType method. By the time control gets to that method, the save dialog box has been used and the save should occur with no delay. Meanwhile, calculations could still be occurring. So if the state is Calculating, I have to request a pause. Either a pause is granted and -calculationDidPause is called, or the calculation completed and -calculationDidEnd is called.
This is getting complicated. Either way I cannot return from the -dataOfType method without some data, so that method has to wait for calculating to pause or finish completely, then gather data, then return.
Thinking about this and the way my program is structured I have come to the conclusion that it will need restructuring in some way to make this work. That implies that I have not designed my objects and their relationships correctly. This is trivially true since I have grown this organically and blundered about as I leaned more of what OO is about.
So my fix is to remove the feature -- if it's good enough for Microsoft, then it's good enough for me.
Now the problem is to disable the Save and Save As... menu items if in the Calculating state. All the other states are OK. I need to turn my attention to the menus anyway: they contain default entries, and I haven't cleaned them up yet.
Running through the menus, I find the following:

About NewApplication needs to be changed. If I select it I get the following:

The text for this is in credits.rtf in my project, so that is easy to fix. It's an RTF, so I should be able to put a description of the program in there with pictures and styled text. Not sure how I change the copyright notice. I don't see a NIB for this window.
I can do without the Services... menu also, since none of them are usable. And I have no prefs.
The File menu looks like this:

I need to control the Save and Save As... so that they are disabled in the Calculating state, but enabled according to regular rules in all other cases. Also I have no Print functions, so those will go.
On the Edit menu, Undo and Redo need to do, and I may have to turn off the undo manager somewhere in my app. In fact the whole menu can go. I support none of this.

The Window menu is fine as it is:

On the Help menu I need to change the menu item text and have it so that it brings up the About box.

The inspector in IB shows me how things are currently connected. The BTNumbers->About BTNumbers menu item shows this:

and the Help->BTNumbers help shows this:

So it looks like I can override -showHelp in MyDocument and redirect that to -orderFrontStandardAboutPanel. The Save menu item looks like this:

Next I have to figure out how to enable/disable menu items.
Disable Saves
The Apple docs tell me how to enable and disable menu items: NSMenu updates every menu item whenever a user event occurs. A menu item is enabled if NSMenu can find an appropriate object that responds to the menu item’s action. If you want a menu item to remain disabled even though an object responds to the menu item’s action, define a validateMenuItem: method for that object.
So here is my code:

I used IB to set the Tag value for the Save and Save As menu items to 1000. That way I know if those items have been selected without doing any complicated work. Anything I don't understand I send to super. Otherwise I apply the rule that I cannot be calculating if I am to save. After I did this I also removed the Open Recent menu item and tagged the Open, Close and Revert items with 1000 as well.
The About Box
I discovered two problems with my approach of disabling the menu items to prevent the user from doing things that do not work (ie I cannot figure how to code without a rewrite): 1) many of the menu items I disabled are not getting disabled, and 2) quitting of course lets the user save, and I cannot prevent the user from quitting the app!
So my solution to this is to ignore it for now and solve a different problem: getting the About box right. It looks like this by default:

The text comes from credits.rtf, a file listed in the Resources folder in XCode. I removed that and replaced it with my own credits.rtfd file -- one with an image. The code that brings up the credits looks for several file extensions: .rtf, .rtfd, .html in turn. The copyright message is in InfoPlist.strings, so that is easily edited.

I edited the text in TextEdit and pasted in a graphic with the equation:

I created that using Grapher and took a screen shot. The 1.0 version number comes from the target information Properties pane. I also included a web link in the text using TextEdit's Add Link feature:

Click and it takes you to the page by opening Safari. Simple and no coding needed.
My app still will not continue if you open a document that was saved in a paused state and click Resume. I have to do some coding to fix that. That's the next step.
Resuming Calculation
The code that starts calculation in BTBagelturfNumberFactory looks like this:

Since loading a document sets up many of these parameters, all of this code is not needed: order, base, value, rangesize, testable, start, calculationComplete, and digits are set up. The last five lines are all that is needed. So I change the code like this:

and have the Start/Pause button click do this:

Now this will spawn a new thread each time I resume, but there is no other way to get calculations going if the document has been loaded. More evidence that my program structure is bad. I really need to have the calculating thread terminate on each pause, but have a way of getting its state such that I can reload the state and start calculating again. That would actually solve the other problem I have of pausing before saving and knowing when the pause has taken effect. Do away with pausing, at least internally and make pause/resume a save state/quit and reload state/start action.
I try this code and nothing happens when I click Resume. Debugging reveals that the client instance variable is nil: no delegate set up. The error was a simple one: I had not reestablished the delegate link between the archived bagelturfNumberFactory and self. So -readFromData:ofType:error needed modifying to look like this at the end:

And hey presto it works. Calculation is resumed and finishes.
Adding Help
Help will be simple: bring up the same dialog as About does. So, in IB look at where About is connected to by bringing up the inspector and clicking on the About menu item: it's connected to -orderFrontStandardAboutPanel in File's Owner (NSApplication). Disconnect the Help item and control-drag from BTNumbers Help to File's Owner and connect to orderFrontStandardAboutPanel.
It works.
Redoing Pause And Resume
The problem with pause and resume is that it is never going to work they way I want it to. I need to redo the code so that the only actions are Start and Stop. Starting either indicates that it must start from the beginning or that it must resume. Stopping always calls a delegate to say that it did stop. Implementing pause/resume means stopping and then starting. The interface to this part of BTBagelturfNumberFactory now looks like this:
and the delegate methods are these:

DidStart and DidStop methods are always called as balanced pairs. So my -calculate method now looks like this. Much simpler.

I count calls to Stop and balance each one with a call to didStop. The lock is still there. This pushes management of start/stop/pause/abort to the delegate method. When didStop is called, the delegate has to know why it was called: was it aborting or just pausing?
-startCalculationWithRangeSize:fromBeginning and -stopCalculation look like this:

Next I have to modify MyDocument to handle start/stop/abort/resume and track state there.
Pause And Resume Works
I edited MyDocument to work with the changes in BTBagelturfNumberFactory. I had to add two state flags:
These are set before -stopCalculation is called and examined in -calculationDidStop. The Start/Pause button click action now looks like this:

The state machine is manipulated as before, but now flags are set and the new methods are used. The -calculationDidStart method is unchanged, but the -calculationDidStop method now looks at the flags and acts appropriately:

Nothing else needed changing. Except the BTBagelturfNumberFactory -calculate method. That was buggy. Here is the new version:

I redid the loop to make sure that -stopCalculation was called if the calculation completed. It also fixes a problem where calculationStop was getting to -1 and going down from there -- forever.
Now my hope is that I can add automatic pausing so that when the calculation is saved (or the user quits and opts to save) it can be paused before it is written to disk. The previous code had foxed me on that, but I think that it will work this time with the addition of more state flags.
Implementing An NSConditionLock
It appears that I need to implement an NSConditionLock to coordinate the action of the two threads when the user saves the document. NSConditionLock allows me to have the main thread wait on the lock and the worker thread set the lock to a specific condition that unlocks the lock. So the logic is to have the worker thread set the condition to one state when it is running and the other state when it exits. The code that needs to know that the worker thread has exited waits on the lock. If the condition is true or becomes true, then execution will continue, otherwise it will block.
I add a new instance variable to MyDocument: calculatingLock.

It will have a value of YES if calculating and NO if not. I initialize it in my -init method like so:
and release it in the -dealloc of course. Now in the -dataOfType:error method I add the following code to pause the calculation and wait on the lock:

At the end of -calculationDidStop I add this code to update the lock state:
and -calculationDidStart looks like this:

I try this and I get a deadlock: the lock in -dataOfType:error never has the right condition. The reason, I realize, is that my -calculationDidStop and -calculationDidStart methods are called on the main thread: so that thread waits for itself.
This means that I will have to move the code into BTBagelturfNumberFactory or have some method in MyDocument that is called by the calculation thread directly rather than through execution on the main thread.
Asynchronous Methods
Let's try another tack. Synchronous methods that are run on the main thread are very nice for GUI work and anything that doesn't want to have locks all over the place, but this situation is different: I do want asynchronicity here. I want to wait on a NSConditionLock and be woken when the condition is satisfied by the other thread. Attempting this synchronously will never work because a thread cannot unlock itself.
I've added two new delegate methods:

The two asynchronous ones will be called on the worker thread. Here is the new -clientCalculationDidStart method:

It makes the async call first, then the sync call. I modified other parts of the code to include these new symbols.
I tried all this and it is still not working. It hangs up on the calculatingLock waiting for condition NO. The log looks like this:

Interestingly the asyncCalculationDidStop message is never output. If I comment out the wait for the lock I get this:

Parts of it are mixed up. "Paused" comes before the asyncCalculationDidStop. So I am suspicious that there is more going on here than meets to eye. Could it be the logging that causes the problem? Here is the code in -dataOfType:error:

One more thing I can try is to make the lock static. I have seen examples that do this, so maybe that makes a difference? If I do that then I can do away with the extra delegate methods.
Polling It Is
Another try. I'm now pretty well convinced that polling is the only way to go. I posted some questions to the Cocoa list and had some replies along the lines of "don't do it the way you are doing it" and "I had crazy trouble too". One person found that NSConditionLock worked as expected only when used with a static. Looking at code on the net confirms that this is the way it is done. That's no good to me, unfortunately because my calculation is in another class and another thread.
So polling it is. I'll add a sleep inside a loop and call a new method on bagelturfNumberFactory that tells me if calculation is ongoing:

I already take note of if the thread has ended, so this works as the calculating flag with the state flipped. My code to poll looks like this:

I sleep 0.1 second each time the calculation is found to be still calculating. And guess what? It still fails!

Now I think the problem is connected with *where* I am doing this, not *how*. What if -dateOfType:error is called in a context that does not allow any other threads to run? That would explain what I am seeing and how nothing works.
I changed -isCalculating to look like this:

It always claims to not be calculating. Now it does this:

Ignoring the Complete state at the end (why does it do that?), it is very odd that the log messages come with calculationDidStop after the machine state has been saved. I really think there is some blocking going on here behind the scenes.
Save As Text
I finally gave up and put a delay in the -dataOfType:error code after I requested that calculation stops. Not sure it is doing any good.
So now I turn my attention to saving the Bagelturf numbers that have been found as a text file. I modified the target information to include a text type (click Targets, select BTNumbers, click Info, then Properties tab):

I listed "Text" as Name, "txt" as Extensions, "text" as OS Types, and "MyDocument" as Class. I selected Binary as the Store Type. Now when I use Save or Save As, I get a choice of document types:

and I can choose Bagelturf Number Document or Text. Nothing happens of course, since I didn't write any code to do that.
The format I will write the data out will be comma-separated with line endings. That way it can be imported easily. The Result and Decimal columns will be the two entries on each line. No clue how to code this yet, since -dataOfType:error needs to return NSData.
Getting Text Into NSData
NSData is just a container for binary from what I can tell. It wraps anything into a form that can be handled as an object. So to write out plain text I have to fill it with the correct text encoding and line endings. NSString has -dataUsingEncoding that looks like it will do the trick. A small test to see if this works:

That writes a couple of lines to a file. If I open the file in TextEdit, it looks OK:

So I modify my code like this to write out the comma-separated values:

and sure enough, it works. Base 16, Order 5 gives 23 numbers that come out like this in TextEdit:

Loose Ends
Cleaning up some loose ends. An assortment of things that needed fixing:How do you choose the location of the document window when it opens? It appears that wherever you have the document window open in IB is where it appears when you run the app. I moved it to a better location than I had it. Subsequent windows cascade from the initial window location.
The Order and base pop-ups always go upwards since the Select string is at the bottom, put there by bindings. I could not figure out how to fix that, so I reversed the order of the strings written into the pop-up. Now the useful Order and Base values are close to the Select string.
The results table has a large font size. How to change that? It turns out to be easy -- if you know how. Select the table and keep clicking until the NSTableView is selected. Now hit Command-T and select the font size from the pop-up. I selected Small System Font.

I also changed the "Press Start" message to "Ready to Search" and "Calculating" to "Searching", used a small scroller, and adjusted the table widths:

The performance is a fraction of what it could be. That's because I use a simple algorithm that has no optimizations. The obvious change is to replace the power calculations with a look-up table. Another is to store differences in the look-up table so that moving from n to n+1 involves adjusting the total not recalculating from scratch. Left as an exercise for the reader.
That's it for that project. I didn't achieve all the things I tried to do, but I learned a great deal in the process, which is what it is all about.
The Bagelturf site welcomes Donations of any size