<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>ToddHa's WebLog : Objective-C</title><link>http://blogs.msdn.com/toddha/archive/tags/Objective-C/default.aspx</link><description>Tags: Objective-C</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Across the [technological] pond</title><link>http://blogs.msdn.com/toddha/archive/2008/10/09/across-the-technological-pond.aspx</link><pubDate>Thu, 09 Oct 2008 23:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8993319</guid><dc:creator>toddha</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/toddha/comments/8993319.aspx</comments><wfw:commentRss>http://blogs.msdn.com/toddha/commentrss.aspx?PostID=8993319</wfw:commentRss><description>&lt;P&gt;I haven't been writing much here recently for a few reasons.&lt;/P&gt;
&lt;P&gt;1. Seattle is *very* nice in the summer time. Why stay inside blogging when you can go &lt;A href="http://maps.live.com/default.aspx?v=2&amp;amp;FORM=LMLTCP&amp;amp;cp=ry42774t4qms&amp;amp;style=b&amp;amp;lvl=1&amp;amp;tilt=-90&amp;amp;dir=0&amp;amp;alt=-1000&amp;amp;scene=3695088&amp;amp;phx=0&amp;amp;phy=0&amp;amp;phscl=1&amp;amp;encType=1"&gt;to the Center for Wooden Boats in Lake Union&lt;/A&gt;, &lt;A href="http://maps.live.com/default.aspx?v=2&amp;amp;FORM=LMLTCP&amp;amp;cp=ry19594t4fbm&amp;amp;style=b&amp;amp;lvl=2&amp;amp;tilt=-90&amp;amp;dir=0&amp;amp;alt=-1000&amp;amp;scene=3695600&amp;amp;phx=0&amp;amp;phy=0&amp;amp;phscl=1&amp;amp;encType=1"&gt;Pike Place market&lt;/A&gt;, or &lt;A href="http://maps.live.com/default.aspx?v=2&amp;amp;FORM=LMLTCP&amp;amp;cp=47.624157~-122.504447&amp;amp;style=r&amp;amp;lvl=15&amp;amp;tilt=-90&amp;amp;dir=0&amp;amp;alt=-1000&amp;amp;scene=3702619&amp;amp;phx=0&amp;amp;phy=0&amp;amp;phscl=1&amp;amp;encType=1"&gt;take a ferry to Bainbridge&lt;/A&gt;?&lt;/P&gt;
&lt;P&gt;2. Got married. We got married back home in Kansas City which took a while to plan for, especially since we were doing it all long distance. Afterwards we went to San Francisco for a few days and took the &lt;A href="http://www.amtrak.com/servlet/ContentServer?pagename=Amtrak/am2Route/Vertical_Route_Page&amp;amp;c=am2Route&amp;amp;cid=1081256321841&amp;amp;ssid=135" mce_href="http://www.amtrak.com/servlet/ContentServer?pagename=Amtrak/am2Route/Vertical_Route_Page&amp;amp;c=am2Route&amp;amp;cid=1081256321841&amp;amp;ssid=135"&gt;Coast Starlight&lt;/A&gt; train back. It's a very pretty ride, but I recommend you get a sleeper car. It's hard to sleep in coach and you don't get all the dining benefits the sleeper car has.&lt;/P&gt;
&lt;P&gt;3. Changed jobs. I'm working on the Mac client for &lt;A href="http://www.mesh.com/" mce_href="http://www.mesh.com"&gt;Live Mesh&lt;/A&gt;. I found the perfect job; not only do I get to work on UI and client code, but I get to spend my day on Macs (and sometimes PCs). Sure, compared to what I'm used to, the APIs are all different, the language is different, the OS is different, but that's the fun of it.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8993319" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/toddha/archive/tags/Personal/default.aspx">Personal</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Objective-C/default.aspx">Objective-C</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Programming/default.aspx">Programming</category><category domain="http://blogs.msdn.com/toddha/archive/tags/OSX/default.aspx">OSX</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Live+Mesh/default.aspx">Live Mesh</category></item><item><title>Assumptions are the mother of all (part 2).</title><link>http://blogs.msdn.com/toddha/archive/2007/04/26/assumptions-are-the-mother-of-all-part-2.aspx</link><pubDate>Thu, 26 Apr 2007 04:33:31 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:2278032</guid><dc:creator>toddha</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.msdn.com/toddha/comments/2278032.aspx</comments><wfw:commentRss>http://blogs.msdn.com/toddha/commentrss.aspx?PostID=2278032</wfw:commentRss><description>&lt;p&gt;In my own time, I've been learning Objective-C for fun. I'm not sure why, perhaps I didn't feel I spent &lt;strong&gt;enough&lt;/strong&gt; time in front of a computer. But I digress.&lt;/p&gt; &lt;p&gt;One of the interesting things I've learned is that the following code works.&lt;/p&gt; &lt;p&gt;Note that I assume we have a class named &lt;em&gt;ArbitraryObject&lt;/em&gt;, and that it has a method that takes no parameters entitled &lt;em&gt;foo&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Objective-C&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject * obj;&lt;br&gt;obj = nil;&lt;br&gt;[obj foo];&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Interesting, this code doesn't crash. In comparison, the following languages all crash when you try to do the equivalent.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject obj = null;&lt;br&gt;obj.foo();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;This is the easy one. We get a &lt;em&gt;NullReferenceException&lt;/em&gt; thrown.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Java&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject obj = null;&lt;br&gt;obj.foo();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;This is another easy one. We get a &lt;em&gt;NullPointerException&lt;/em&gt; thrown.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;obj = None&lt;br&gt;obj.foo()&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Since we don't have to type what &lt;em&gt;obj&lt;/em&gt; is, we get an &lt;em&gt;AttributeError&lt;/em&gt; talking about how the &lt;em&gt;NoneType&lt;/em&gt; object doesn't have an attribute of &lt;em&gt;foo&lt;/em&gt;. Not exactly the same as before, but close enough.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;C++&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;code&gt;ArbitraryObject * obj = 0;&lt;br&gt;obj-&amp;gt;foo();&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Note that this isn't the entire code required to get the program to crash (and I'm not sure what spurred me to prove to myself that it wouldn't work). The MS VC++ compiler was optimizing my defects away in different ways. I had to add an instance variable to the ArbitraryObject class, assign it in the constructor, and have foo return the variable. Then in the calling code I printf'd it. But I'm ignoring this for simplicity.&lt;/p&gt; &lt;p&gt;But regardless, it's an access violation error.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;What we've proved is that Objective-C works very differently from how other programming languages work. There are some pros and cons of this, depending on your perspective. It's just important to know how things work.&lt;/p&gt; &lt;p&gt;A couple notes : &lt;/p&gt; &lt;ol&gt; &lt;li&gt;I use&amp;nbsp;&lt;em&gt;nil&lt;/em&gt;, &lt;em&gt;null&lt;/em&gt;, &lt;em&gt;0&lt;/em&gt;, and &lt;em&gt;None&lt;/em&gt; interchangeably.&amp;nbsp;  &lt;li&gt;I'm assuming the compiler hasn't optimized your (possibly intentional) errors away.  &lt;li&gt;I really have nothing against any programming language or technology, so please don't assume that I'm some [arbitrary technology/programming langauge] basher or fanboy (even though Objective-C is primarily an Apple&amp;nbsp;language, and Apple is a competitor to Microsoft).&amp;nbsp;This is just another example of where you might think things work one way, and work a different way completely. &lt;li&gt;I find this particular example fascinating.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Comparing Objective-C performance to C#, Java, and Python isn't really fair as they all have to be translated into machine language at runtime.&lt;/p&gt; &lt;p&gt;However the C++ comparison&amp;nbsp;is fair. What I'm assuming is happening in Objective-C (without diving into&amp;nbsp;PPC assembly) is that there's a check before each function call that says, "Hey, if this address is nil then jump over this block of code that sets up for and executes the&amp;nbsp;function call." So assumedly you have a some extra instructions every time you make a function call. Not a big deal, especially these days where we have a bazillion clock cycles per second, but definitely something that you need to think about if you're trying to squeeze every cycle out of the processor.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Program Flow&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;This is the main root problems I would assume. I'm going to use C# to flesh out the code, but you can easily translate it to Objective-C. More on this after the code.&lt;/p&gt; &lt;p&gt;Let's go back to our example code and flesh it out a bit in order to prove a point.&lt;/p&gt; &lt;p&gt;&lt;code&gt;public class ArrayWrapper&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;private&amp;nbsp;static int [] array = new int[] { 1, 2, 3, 4 };&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private static int index = 10;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static SetIndex(int index)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ArrayWrapper.index = index;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int GetIndexedValue()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // note that this crashes&amp;nbsp;if index is the default value&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ArrayWrapper.array[ArrayWrapper.index];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;br&gt;public class ArbitraryObject&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //&amp;nbsp;we don't have to define an empty constructor, but will anyways!&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public ArbitraryObject() { }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void foo()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ArrayWrapper.SetIndex(2);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/code&gt;&lt;code&gt;&lt;br&gt;}&lt;/code&gt;&lt;/p&gt; &lt;p&gt;And now for the driver code function.&lt;/p&gt; &lt;p&gt;&lt;code&gt;public void DriverFunction(ArbitraryObject obj)&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; obj.foo();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // here we have assumed that obj.foo() did it's job and set the&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// index of the ArrayWrapper to a valid value&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(ArrayWrapper.GetIndexedValue().ToString());&lt;br&gt;}&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Ok, so this seems like a really stupid example, but it's point is to show that you're assuming that the ArbitraryObject class worked in order for the rest of the function to work.&lt;/p&gt; &lt;p&gt;Let's run some tests. These are based on whether or not obj.foo( ) worked. I'm not going to translate this to Objective-C, but you can easily see what happens.&lt;/p&gt; &lt;p&gt;C# Tests&lt;br&gt;Valid instance of Arbitrary Object : Wrote out "3" to the console.&lt;br&gt;Null reference : NullReference exception at line &lt;em&gt;xxxx&lt;/em&gt;.&lt;br&gt;&lt;br&gt;Objective-C Tests&lt;br&gt;Valid instance of Arbitrary Object : Wrote out "3" to the console.&lt;br&gt;Null reference : Out of bounds error.&lt;/p&gt; &lt;p&gt;Ok, so we still get an error in Objective-C. And it's relatively easy to debug what's happening. But if the user gets this, the app will have crashed. And they'll get upset. Arguably, they'd get upset in C# too.&lt;/p&gt; &lt;p&gt;But what if the default index was valid? Like 0? We wouldn't crash, but we'd get incorrect results. Which is a LOT harder to debug. But doesn't crash for the user. Maybe it affects the final results that they're looking it for. Maybe it doesn't.&lt;/p&gt; &lt;p&gt;My point to all this is that this introduces a lot of subtleties to debugging something that you have to think about when writing or debugging the code. I'm not saying that it's bad at all. Sometimes you don't care about if the line fails or not -- and you don't have to write a bunch of function calls prefixed with&amp;nbsp;&lt;em&gt;if (reference != null)&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;Another reason to not make assumptions about the way things work (especially in new programming languages). :)&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=2278032" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/toddha/archive/tags/Python/default.aspx">Python</category><category domain="http://blogs.msdn.com/toddha/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Objective-C/default.aspx">Objective-C</category><category domain="http://blogs.msdn.com/toddha/archive/tags/C_2B002B00_/default.aspx">C++</category><category domain="http://blogs.msdn.com/toddha/archive/tags/Programming/default.aspx">Programming</category></item></channel></rss>