As a person who major in CS, I have interest in fundamental technology or techniques like compilers, OS, 3D graphics, computer vision, parallel systems & distributed systems. So, one of the reason I started to work with 3 major OSes, i.e. Windows, Unix and Mac, and have had lots of interest in their architectural design. Therefore I like to work with different frameworks and compare their design or philosophy behind them.
I think OS architecture is like a whole picture, while frameworks are each part of the OSes. What architectural design an OS has is reflected to its frameworks. When overall architecture design affect how they work, how their components are related one another and so on, frameworks for them should be designed as such. This is one of the reason I think Apple should have filed with OS architectures than their visual UI design against MS and Google.
Here, I would like to show the very difference between .NET and Cocoa. If you have followed ToolBox API and Win32/MFC, you will see similarity between Apple’s and MS’s. Also, there are similarity between Cocoa and .NET. I think it is because Objective-C/Cocoa is in the SmallTalk camp which test OOP concept in academia and geared toward SE, while C++ is in Simula camp which is more for real industry field. Because C++ is for more real field, it should have been compromised with many restriction like CPU speed etc. Also the C++ has been evolved for everything for all people. So, although C++ was introduced as THE OOP language, it has many different concept like meta programming, ad-hoc polymorphism. Also, because of that it also contains its syntax which became somewhat bad and some concept got to have many semantics. (e.g. extern vs. static ) C# is not too different from C++ in that. Although MS streamlined C# from C++. (actually C# was influenced more by Java at first. But as its name suggests it has the face of C++. # in its name is somewhat amusing. When they call it, don’t forget that it is called “sharp” rather than “pound”. # in musical notation is half higher than a note it is attached too. So, C# is C++ in that sense. ) I can feel those philosophy to be all for all from C#.
However, Objective-C and Cocoa was evolved to be focused to increase productivity. So, when using Objective-C and Cocoa, you naturally become to focus on core logic rather than “how to achieve that”. Objective-C is more simple and Cocoa is designed to be very intuitive and powerful.
OK. Let’s see how Objective-C/Cocoa achieves “GUI code on main thread”.
- (IBAction)doInThread:(id)sender
{
[NSThread detachNewThreadSelector:@selector(doSomethingMethod:)
toTarget:self withObject:nil];
}
// Thread method
- (void)doSomethingMethod:(id)object
{
// Calls appendLogMessage: on main thread
[self performSelector:@selector(appendLogMessage:)
onThread:[NSThread mainThread]
withObject:@"Do something..."
waitUntilDone:YES];
}
- (void)appendLogMessage:(NSString *)messageString
{
NSTextStorage *textStorage = [m_logBoxView textStorage];
NSUInteger theLastPos = [textStorage length];
[m_logBoxView setSelectedRange:NSMakeRange( theLastPos, 0 )];
[m_logBoxView insertText:[NSString stringWithFormat:@"%@\n",
messageString]];
}
It’s very intuitive. (Don’t confuse with that you don’t understand Obj-C code. Once you get used to it, it is very easy and straightforward. ) The appendLogMessage: is written just like a normal message/method.
Now, let’s check how it looks in C#/.NET.
#region MSDN way
private void m_doSomethingButton_Click(object sender,EventArgs e)
{
m_choreThread = new Thread(new ThreadStart(this.StartThreadLoop));
m_choreThread.Name = "MSDN Thread";
m_choreThread.Start();
}
// Thread method
private void StartThreadLoop()
{
// This is a thread loop
int i = 0;
while (i < 10)
{
// 1. Call WriteLogMessage()
this.WriteLogMessage(String.Format("Do chores hard!!! {0} from {1}", i, m_choreThread.Name));
i++;
}
}
// 2. Visit this in the non-main thread space
// 5. Visit this in the main thread space
private void WriteLogMessage(string msgString)
{
// 3. If it is still in the context of a non-main thread
if (m_logTextBox.InvokeRequired)
{
WriteLogMessageCallback writeLogMessageDelegate = new WriteLogMessageCallback(WriteLogMessage);
// 4. Invoke in its main thread space
this.Invoke(writeLogMessageDelegate, new object[] { msgString });
}
else
{
// 6. Call this in the main thread space.
m_logTextBox.AppendText(msgString + Environment.NewLine);
}
}
#endregion
I commented how things are visited in the C#/.NET case to help your understanding. So, to you, who use the framework, .NET case prevent you from concentrating on the main logic. In other words, you should know how things work in C#/.NET.
One of the virtue of OOP is data hiding and encapsulation. Although it says “Data Hiding”, it’s not only about “Data” but also “how it works internally.” C#/.NET fails in this area seriously as you can see. In other words, you should be aware of in which thread context the WriteLogMessage() is called and the method should be implemented with that knowledge.
Compared to that, messages in Objective-C/Cocoa can be written just like usual messages.
Then, are they really different? Couldn’t MS make their .NET framework as elegant as Cocoa? No. I don’t think so. It looks to me that Cocoa’s underlying code could be similar to that of .NET. The difference is that how much Apple people refined their framework by considering people who actually use their framework and design the framework to let people to focus on their own logic not on how Apple implemented this and that.
Then, let’s try to make it look similar to that of Objective-C/Cocoa.
#region Cocoa Way
private void m_doSomethinginCocoaWayButton_Click(object sender, EventArgs e)
{
WriteLogMessage2(Environment.NewLine + "----------------------------" + Environment.NewLine);
m_choreThread = new Thread(new ThreadStart(this.StartThreadLoop2));
m_choreThread.Name = "Cocoa Thread";
m_choreThread.Start();
}
private void StartThreadLoop2()
{
// This is a thread loop
int i = 0;
WriteLogMessageCallback writeLogMessageDelegate = new WriteLogMessageCallback(WriteLogMessage2);
while (i < 10)
{
this.performOnMainThread(writeLogMessageDelegate,
new object[] { String.Format("Do chores hard!!! {0} from {1}", i, m_choreThread.Name) } );
i++;
}
}
private void performOnMainThread( WriteLogMessageCallback methodToInvoke, object[] parameter )
{
if (m_logTextBox.InvokeRequired)
{
this.Invoke(methodToInvoke, parameter);
}
}
private void WriteLogMessage2(string msgString)
{
m_logTextBox.AppendText(msgString + Environment.NewLine);
}
#endregion
Don’t bother with the method name “performOnMainThread“. It’s not our interest. Whatever the name is, it doesn’t matter. What we need to focus on here is the pattern of how WriteLogMessage2() is called.
Also, additionally assume that Object class in .NET framework, which all classes are inherited from, contains the performOnMainThread(). Then like Cocoa, you can ask an object to invoke a given method on main thread. Then you, as a application program developer, can write the method to be invoked without worrying about knowing how those invoke system works.
Similar things happens with timer invocation. If you want to invoke a message at certain intervals in Cocoa, the code is very straightforward and very clean. However, in Win32/MFC case, the OnTimer() handler should check what timer triggers this timer event. In this case, it looks to me that Apple people utilizes signals and events. (Signal is so-called H/W events while event is called S/W event, if you want to be specific about the terms. ) I will not show sample code for that here.
Point here is that the level of refinement is higher on Apple’s. Cocoa framework is designed for SE more in mind, while MFC/.NET are more about “Let’s put this on the market as quickly as possible.” Good news is that.NET is more similar to Cocoa than their previous frameworks, because NeXT showed a future a while ago and MS looked to adopted that.
I always wonder why MS simply adopted Objective-C/Cocoa for their platform development. Well, C#.NET was a kind of a gun toward Java and MS languages can share the same .NET framework. So, there is slight difference, but even with Objective-C/Cocoa, there is a language bind. Well.. it’s true that people should make their own Cocoa equivalent.. yeah.. that can be the major issue to MS.
( Well.. I know that not choosing Obj-C/Cocoa or OpenStep by MS was also due to market situation, marketing, etc, but here I would like to focus on technical side. )
I wonder how F-Script people and Ruby Cocoa people bridged their language to Cocoa. (Script Bridging tech.. )
Recent Comments