Why Objective-C is Hard
ashfurrow.com
ashfurrow.com
The syntax IS absolutely horrible if you ask me as it results in crazily verbose ways of expressing stuff. Everything is "too meta" and there are very few first class parts of the language. It still FEELS like it's hacked together with C macros (which was what it originally was).
Add to that the reference counting implementation (when GC is not enabled which you can't do on iOS) and it's just painful. Also the lack of any decent threading abstraction - ick.
I think there is a lot of hype around it. It's not where we should be in 2012. Android does better with bastardised Java if you ask me.
What? Grand Central Dispatch is a lot easier to work with than most explicit threading mechanisms and with the new block support is a lot less verbose than the typical Java thread-based approach.
Java/C# don't need a language extension - the functionality exists outside the semantic boundary of the language. Another cludge in Objective-C.
C# (ThreadPool/async framework/Windows workflow) and Java (ExecutorService/lots of 3rd party frameworks) have had them for years with well-known communication, thread safe data structures, concurrency and locking semantics.
Most of the verbose mess you see in Java threads is because the person writing it doesn't know much.
[NSArray arrayWithObjects:@"Hello", @"World"];
Of course it crashes! You have to add a nil sentinel value to the end of your list of objects, silly. And of course it compiles with only a warning, just like when you leave out the @ that makes the difference between a C string literal and an NSString. Those errors will crash your program as soon as the code is run, but they compile as valid Objective-C. Things like that are just a nuisance if you tell the compiler to treat warnings as errors, though. If you really want to know why Objective-C is hard, why not trust the authorities on Objective-C, namely Apple?Where Apple tells you you will screw this up is memory management. To start with, there are four different memory management schemes: C memory management for C objects, manual reference counting, automatic reference counting, and garbage collection. You get to choose two, of which C will be one. Objective-C originated as enhancements on top of C, and Objective-C programmers writing Cocoa apps still have to rely on C APIs for some functionality, so you'd think by now they would have provided a better way of managing, say, the arrays of structs you sometimes have to pass to the low-level drawing functions. Nope; everyone still uses malloc and free. Failure to make malloc and free obsolete is hard to forgive.
From the other three memory management methods, pick one. (Different OS versions support different ones.) Automatic reference counting (ARC) is the latest and apparently the new standard, though manual reference counting is still supported, and GC is still supported on Mac OS. Reference counting requires a little bit more thinking than garbage collection. For example, since the Cocoa APIs were written with reference counting in mind, some objects, notably UI delegates, are held as weak references to avoid reference cycles. You basically have to manage those objects manually: create a strong reference to keep the object alive and then delete the strong reference when you decide it's okay for the object to be collected. (I'm not sure, but I think this is true even if you turn on GC, because delegate references remain weak.)
All reference-counting systems have that problem, but at least they have the benefit of determinism, right? When you pay that much attention to object lifetimes, you get to piggyback other resource management on top of memory management and kill two birds with one stone. (In C++ it's called RAII, and it's the saving grace of C++ that almost completely makes up for C++'s other warts.) However, according to Apple, this technique should not be used with Objective-C:
You should typically not manage scarce resources such as file descriptors, network connections, and buffers or caches in a dealloc method. In particular, you should not design classes so that dealloc will be invoked when you think it will be invoked.
Why not? Application tear-down is one issue, but that doesn't matter for resources that are recovered by the OS when a process terminates. "Bugs" are given as a reason, but I think they mean bugs in application code, not in the Objective-C runtime. The main reason, then, is that if your Objective-C programs leaked file descriptors and network connections as often as they leaked memory, the world would be in a sorry state:
Memory leaks are bugs that should be fixed, but....
Remember the "I don't mean to be a ___, but..." discussion?
Memory leaks are bugs that should be fixed, but they are generally not immediately fatal. If scarce resources are not released when you expect them to be released, however, you may run into more serious problems.
In other words, if you really need something to work reliably, you had better use a different mechanism, because you don't want your management of other resources to be as unreliable as your management of memory. That's a pretty strong statement that you will screw up memory management whatever your best efforts.
So apparently Objective-C memory management is hard. That's what Apple thinks, anyway.
The quotes are from the "Practical Memory Management" section of Apple's memory management programming guide: https://developer.apple.com/library/mac/#documentation/cocoa...
How is the compiler supposed to know you meant NSString or C-String?
Apparently it's a feature in Xcode 4.4 in the beta release of the Mountain Lion SDK. There's no developer preview for Lion, though. Fingers crossed that Xcode 4.4 will be released for Lion and not just for Mountain Lion....
Not sure why Apple hasn't been more aggressive in pushing it for Cocoa development. Maybe because they don't trust it to perform well, yet, on iOS devices and don't want to promote it until it can be used anywhere as a replacement for Objective C.
This is not surprising given that both Ruby and Objective-C xeroxed their object models from Smalltalk.
Clever, Mr. Kay
I understood his point to be mostly that syntax melts away after time, and you will just see the concepts. It seems that you are objecting to the notion that "Programming in Objective-C is easy," but I don't see that in his post.
Do they propose an alternative mechanism to handling resources other than reference counting? As you state, RAII breaths life into c++, given how well it works for all types of resources.
It sounds like the above statement is possibly being made in anticipation of the introduction of garbage collection, which would make piggybacking resource destruction non-deterministic. Whereas, it could also be interpreted as a very strong reason to favor manual (maybe automatic) reference counting, and eschew GC entirely. I don't know objective-c very well, but I wonder if the use of GC has generated these arguments against it from within the OSX developer community.
Great! The best C++ compliment I've ever read.
Also, syntax is the worst place to start learning Objective-C imho 'cos there can be a lot of it to learn if you come from a non-smalltalk world. The best place I've found is to dive straight into the core runtime function objc_msgSend. Once you grok that, and see that you could write down the core runtime in a handful of C functions in an hour or so, everything else -- classes, categories, protocols, delayed invocation, remote invocation, proxies, posing, key-value coding -- finds a "natural" slot in your brain. As a bonus, as you get to the more "advanced" features unique to the system (relative to, say, C++) such as key-value coding, you see how the dynamism of the language plays to support all of that. (Disclaimer: Yes, this is how I got it, but I don't know whether it is generally good way to approach it, though I'd recommend it. Maybe I should write a tutorial on it.)
If you start by looking at the syntax and going "ugh", you'll be missing all the neat ideas in the system ... including, imo, the older memory management system that many complain about. I've, for example, used the "auto release pool" idea in C++ to relieve colleagues of the need to think about ownership and lifetime in relatively isolated corners of a system while considerably simplify api design and staying performant. If you're looking for "predictable performant garbage collection", this is a reasonable design candidate.
language syntax and it's consistency is (imho) the UI of the language. you get put off by ugly as often as you care to look at it...
I guess what I'm saying is after all these years I want to work on a higher level, as a result I've started to play with Clojure and functional languages. Whether I'm idealizing functional/clojure life, I'll soon find out, but the appeal is very high to spend my time dealing with problem complexity, not language/framework ones.
Holding off on ARC is only advantageous if you need to support iOS versions before 5.0, but ARC is the future of iOS.
Like, SWT objects in Java. Or file descriptors. Or DB connections.
Because Objective-C targets everyday desktop apps and mobile apps. In that space, manual memory management still wins the day.
For example, in Windows and Linux DESKTOP those kind of apps are ALSO made in C++ or C.
Java and C# are for the web server and the CORPORATE desktop (in-house apps).
Not many major end user apps outside the enterprise are made with either. Not any famous, widely used ones, anyway. Azureus, maybe, and a few dozen more.
Evernote actually did a great post about switching from C#/WPF back to a C++ app and how it actually let them move faster. Pretty interesting read. http://blog.evernote.com/2010/10/26/evernote-4-for-windows-i...
It's nothing to do with the language.
It's not good progress - it's just a deeper abstraction.
I can't help but feel if MS had paid more attention to perf (maybe re-platform it on top of Direct2D in the .NET 4 timeframe, instead of going all in on WinRT) things would be a lot better.
Anyway, thanks for sharing those pain points.
Agree with performance. I hope WinRT is better. I have little faith based on my experience with Win8 so far but it's not RTM so I shouldn't comment on it yet.
Another example: http://www.youtube.com/watch?v=5AZzPZ0kjyk
I now had a ThinkPad X220 which is roughly the same CPU as the MacBook Pro and has twice the memory and it never even gets warm.
http://en.wikipedia.org/wiki/Dalvik_(software)
"Then they are converted from Java Virtual Machine-compatible .class files to Dalvik-compatible .dex (Dalvik Executable) files before installation on a device. The compact Dalvik Executable format is designed to be suitable for systems that are constrained in terms of memory and processor speed."
And don't games use the Android NDK?
Dalvik does fix the startup issue with better class files, yes.
Also, as of a few years ago, the only performance-related reason why the JVM wasn't a popular language for desktop GUI apps was startup time. (In the mobile space, it might be true that Java isn't fast enough on current hardware. My experience with Android hasn't been very inspiring, for sure.)
Keep in mind that desktop GUI frameworks take a HUGE amount of time and labor to create, and almost all of the excitement has been in web apps for the last decade. The status quo in GUI frameworks is heavily colored by history. All of the major GUI application frameworks are ancient and reflect the linguistic realities of the year 2000 much more than they reflect current technology.
I don't think so. Besides startup time, Swing was always slow --an over-engineered mess. For some Java people it was always "fast enough in the latest version" (like for some Linux people it was always "the year Linux wins over the Desktop"), but even the best Swing UI had perceptible lags over a bog standard native. Heck, even SWT that's half-native has huge GC related lags in Eclipse.
Swing also had the uncanny valley effect, trying to mimic native UIs. And even when they tried to bypass the issue with custom l&f like Alloy et al, they couldn't, because the uncanny value is mostly due to how the controls BEHAVE and not with their style (that's why in, say, OS X, you can use apps styled like Aqua and others styled like Metal at the same time and you don't get the "uncanny valley" effect).
The Eclipse framework itself is plenty fast, and UIs based on Eclipse RCP can be quite snappy. (Except for that damned startup time.) Swing's a mess, but if you're looking for the technical limitations of a language platform, it's the best performers that are relevant, not the worst performers. Otherwise, iTunes is evidence that even C is just too slow.
I find it really weird that there's no mention of Smalltalk, which is exactly where the weird syntax comes from. It's also where the notion of IntentionRevealingNames comes from, which the author wonders about.
http://c2.com/cgi/wiki?IntentionRevealingNames
(That's the Ur wiki, BTW.)
Thoughtful post but with less than stellar marks for research.
Methods are actions, not objects, so the most concise description for a method is usually a verb. Describing it as a noun instead requires adding prepositions and turning verbs to the gerund '-ing' form.
I realized this because I write both Ruby and Objective-C, and sometimes write basically the same thing in idiomatic forms of both languages. In idiomatic Ruby method-chaining, your code is a series of verbs with the relations between the actions defined by the '.' or the '()' signs, rather than by words such as 'to', 'from', 'with', or 'by' present in the name of the method.
What really creates the impression that Objective-C speaks in terms of nouns is that Cocoa tends to promote immutable objects more than Ruby does (e.g. the only way to get an immutable string or array in Ruby is to freeze a mutable one, while you'll almost never get a mutable array in Cocoa unless you create one yourself), so you probably do spend more time asking your objects for other objects than you do in Ruby.
Although the verbosity can get overwhelming, I actually like this about Objective-C. In terser dynamic languages, I'm constantly having to confirm (either mentally or in the docs) which methods mutate and which return a new object. Cocoa's naming conventions mean I pretty much never have to do that.
pop
push
shift
unshift
<<
clear
replace
delete (and friends)
keep_if
As an even more extreme example, IO contains precisely one bang-method, despite the fact that probably 75% of IO's instance methods are destructive.The general rule seems to be that if there's a mutating and non-mutating version of the same method, the mutating one will get a bang, but when there's a mutating method with no counterpart, it might get a bang but probably won't.
- There is a safer alternative (e.g. mutating vs. non-mutating or skipped validation)
- It should only be called once in a process (e.g. Padrino.start!)
- It is non-reversible (many statemachine libraries use action! as the way to invoke state transitions, which might not be reversible)
This doesn't mean that every method needs to be suffixed by ! if it does something destructive. `delete` in the context of an ORM is standard, so it doesn't have a bang. The whole point of `pop` is to manipulate the receiver: no point in warning about it. IO is always destructive, so ! doesn't make sense either.Yegge basically completely agrees with you. Once I started thinking of OOP in these terms it helped me, as a programmer, a lot.
I wonder if we can relate your observation to the fact that "messages" (nouns) are preferred to "methods" (verbs) in Obj-C.
With it's C-based syntax, Objective-C isn't as clean as Python or Ruby, but due to the explicit naming conventions, I think it's more readable than Java or JavaScript.
if ([[data objectForKey:@"released"] isKindOfClass:[NSNull class]]) {
if ([[data objectForKey:@"posterUrl"] isKindOfClass:[NSString class]]) {
They weren't right next to each other, and at a glance, I misread to assume they were doing the same thing. There's too much shit in the way of the actual differences (NSNull vs. NSString in this case) that I have a bad tendency to gloss over the details. Coming from ruby, the closest syntactical equivalent: if (data['released'].class == NilClass) {
if (data['posterUrl'].class == String) {
Is so much clearer to me when glancing through code. That doesn't even touch on how you'd actually write that sort of thing (data['released'].nil?) which is infinitely more concise than either example. I know this is a bit of a contrived example, and I certainly could find better ones. I just find the 120 character long method evocations to consistently blur the details for me, and this just happens to be the freshest instance.To be fair, I've only been doing iOS stuff for about a month. Does this trend reverse after you've been writing obj-c for a while?
For instance, I look at the first example you posted and I know exactly what it does. It's very natural for me to read.
FWIW, extracting nested expressions into local variables helps a lot with nested method calls.
connection:didReceiveResponse: addObserverForName:object:queue:usingBlock: drawAtPoint:forWidth:withFont:minFontSize:actualFontSize:lineBreakMode:baselineAdjustment:
Personally, once you have more than two humps in your camel case, my eyes have trouble scanning.
HWND hwnd = CreateWindow("MainWClass", "Sample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
(HWND) NULL, (HMENU) NULL,
hinstance, (LPVOID) NULL);
And here's a long method call in Objective-C: NSString *filtered = [unfiltered stringByReplacingOccurrencesOfString:@"verbose"
withString:@"explicit"
options:NSCaseInsensitiveSearch
range:NSMakeRange(0, [unfiltered length])];
Admittedly not equivalent examples, but I couldn't quickly find a Cocoa method call with eleven parameters. My argument is that if you're not intimately familiar with these two calls, CreateWindow() is pretty cryptic. You only get the most general sense of what it's doing without consulting a reference. Objective-C's strange method naming scheme (taken from Smalltalk) makes complex method calls much easier to understand in situ. NSString *filtered = [unfiltered replace:@"verbose"
with:@"explicit"
options:CaseInsensitive
range:Range(0, [unfiltered length])];
Of course, I'm making assumptions about what those parameters mean. But I find this much more clear, assuming the intentions are what I think they are.On the second line, you didn't mention at all what is passed in.
For the last two, removing the NS prefix would work if Objective-C had some kind of namespacing support. Currently it doesn't, so the NS prefix is kinda needed.
I'm not sure what you mean by not mentioning what is passed in. Keep in mind: I have never programmed in Objective-C. I am going on intuition alone.
No namespace support is a bummer - it means you're going to end up with long identifiers all over the place.
Allow me to introduce you to NSBitmapImageRep, which holds the dubious honor of being initialized by the longest public selector in all of Cocoa. Here's a contrived example:
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:data
pixelsWide:640 pixelsHigh:480
bitsPerSample:8 samplesPerPixel:3
hasAlpha:NO isPlanar:YES
colorSpaceName:@"NSCalibratedRGBColorSpace" bitmapFormat:NULL
bytesPerRow:0 bitsPerPixel:0];
edit: formattingVerbose selectors make Objective-C self-documenting at the cost of extra typing. But autocomplete solves this problem because you only ever have to type 2-5 characters to insert the method you want (once you are experienced enough to predict what autocomplete will spit out).
Objective-C naming conventions form predictable patterns. Inexperienced programmers gripe because they have yet to figure out these patterns, good programmers love Objective-C because they understand these patterns and can therefore predict the name of a method and its arguments and great programmers write their own classes that use these patterns.
Cocoa on the other hand requires much more learning curve. Also apple could improve their documentation.
I'm currently working on a OSX app, and Objective-C has been a breeze, with the new ARC is even more easy to work with.
I followed Google's supplied tutorial for creating a tabbar app, and asked one of the Android devs who works with me to come take a look at the finished result.
"Oh", he said, "that's deprecated now. We don't do tab bars like that any more. We use fragments instead". And sure enough, when I looked closely, Eclipse was telling me what I'd done was, in fact, deprecated and Google recommended a different approach.
Except I'd followed their main tutorial for Android, step by step. Compare this with Apple, who have consistently updated their documentation for each API release. How Google could possibly think it's a good idea to deprecate a major platform feature for fragments (a good thing) and not update one of the most popular tutorials on their site to reflect this (the 'Hello Views' tutorial) is beyond me.
Do you have any examples of big libraries where "they could improve the documentation" is untrue? I can't think of any offhand.
(This is not snark. I'm honestly interested if you do.)
APIs are perpetually under-documented, in my experience, so the parent comment's observation is essentially an empty statement.
The vaunted Core Data + iCloud integration is woefully underdocumented (actually, it's practically undocumented), with the main resource being a mega-thread on Apple's dev forums, where every few pages someone from Apple will chime in with ever more confusing suggestions, and yet never updated sample code nor docs.
I really don't think "shitty documentation" is a uniquely Android thing, nor is it something iOS has resolved.
What you should probably decide for yourself is if this article makes it seem harder than it is. His conclusion about Automatic Reference Counting is on the money, but that's about it.
"When learning Objective-C, it's not just a language or a framework or a runtime or a compiler, it's all of these things". No is not. These are different.
If anyone is considering learning this language, there's a bunch of unsolved problems that frequently include writing new libraries.
Cheers.
It might be verbose, but you have a clear separation between C and Objetive-C. If it doesn't contain "[]" or "@", my brain can just parse it as C code.
Obj-C was the first language I learned after Python. I remember the 2nd month in, it went from being difficult to read, to extremely easy.
Obj-C code can be written terribly, like this:
NSString *someString = @"hello what's up?";
NSMutableString *anotherString = [NSMutableString stringWithString:@"I have more to say, don't I?"];
NSArray *stringArray = [NSArray arrayWithObjects:someString, anotherString, nil];
NSUInteger stringArraySize = [stringArray count];
Messy Obj-C code! Human eyes like simplicity, like right angles, and columns. Same code, more readable: NSString *someString = @"hello what's up?";
NSMutableString *anotherString = [NSMutableString stringWithString:@"I have more to say, don't I?"];
NSArray *stringArray = [NSArray arrayWithObjects:someString, anotherString, nil];
NSUInteger stringArraySize = [stringArray count];
Takes an extra few seconds of typing, but goes miles.If a newcomer checked out the online documentation for contentStretch they would find:
"Defines portions of the view as being stretchable. This behavior is typically used to implement buttons and other resizable views with sophisticated layout needs where redrawing the view every time would affect performance."
There's also a lot of good arguments as to why dot syntax is often NOT what you want to do.
For instance, a someCALayer.frame will give you the frame of that layer based on its anchor point, position and bounds. However, you can't do myLayer.frame = someRect [edit: as pointed out below, you can do this -- but the results may not be what you expect].
The introduction of the 'simpler' dot syntax, in that example actually makes things harder for a new programmer.
So, I don't agree that syntax is why Objective-C is hard. Intimidating because of syntax, perhaps. But, once someone begins coding (IMHO) it can be one of the easiest languages.
My school taught Pascal in the intro to comp sci class. I found it incredibly difficult (well, maybe dull is a better word). I then self-taught myself actionScript (late 1990's). I then self-taught myself Objective-C, and I have to say it really just took a Big Nerd Ranch guide and I was off and running. It takes years to become fluent, but I really think that when someone grasps the basics of Objective-C, over time it is one of the most intuitive languages.
As a concrete example, you actually can do myLayer.frame = someRect. The results might not be what you expect, especially if the CALayer exists in a hierarchy already and if the anchor point isn't the centre of the layer, but how would you know that if you hadn't experimented already?
In this particular case though, who would be playing with the CALayer class without ever having touched the documentation? The overview of view geometry (frame, anchor point, bounds, position) is second only after the Core Animation introduction in the docs. And it's pretty clear: when you get a frame from a layer, it is an implicit function of the anchor point, position and bounds -- but the frame itself is not stored (when you set it).
So, if you're using dot syntax to store properties throughout your code, and then you use it on the frame property, a casual reading of the code might lead someone to think that you could retrieve that value later and have it be the same.
(Here's what Joe Conway says about the dot-notation syntax: http://weblog.bignerdranch.com/?p=83 )
How many hackers out there always read the entire manual before playing around? I'd wager most.
I agree that Objective-C is slightly schizophrenic about the dot-syntax, but I would argue that dot-syntax for getters and setters is easier for a newcomers to learn.
If someone is having a hard time learning Objective-C, maybe the real suggestion is to start by reading at least a bit of the manual.
The article is a complete waste of time.
But then I've never really understood why people think it's acceptable for languages to insist that you do this:
myfunction("First argument","Does this one really go second?","Is there even a third?")
The only thing i would say is uniquely hard about Objective C is getting your head around some of the APIs, but then again that can apply to any language.
Example, let's draw a line and an ellipse in drawRect:
CGContextRef ctx = UIGraphicsGetCurrentContext(); //CGMove the point somewhere? //CGLineTo something //CGDrawEllipseInRect or something //stroke or fill? CGFillSomething maybe? //do i need to end the context?
Maybe it's a mental block on my part, but I can _never_ remember how to do this and always have to look it up, probably because it's not part of the standard UIKit and not used on daily basis. I guess I would just like to see the Quartz stuff conform more to UIKit naming conventions (but because it's based in C, I understand why it's not)
The first is the traditional Cocoa pattern of a method that does useful things, which looks like this:
- (void)beautifullyNamedMethodFor {
void* ugly_ptr_type; // and around 45 more
CFObscurePtrRef* .. = CFObscureObsoleteFunction(NULL, NULL,.....); // 56 arguments
// to the callback omitted for brevity
...*....(*foo)...->(*x++);
// and so one - with 45 lines of NULL ptrs passed as void* to CF calls
// juggled and incremented ad absurdum until your eyes bleed.
}
So on the surface it's a beautiful Smalltalkish thing, while down below it's usually all hairy C, pointers and null-terminated strings and Core Foundation callbacks right out of MacOS 7 (especially if you want anything useful to be done that is not in Cocoa by default). This always seemed to me to be a deception in a way.Another pet peeve of mine is the same agony of choice that is object variables (pointers versus values). When I want to return something or declare a variable, even when I am in the rose-tinted-glasses Cocoa world of beautifully-named methods, classes and keyword arguments I still have to put the dreaded death star in front of just the right things (and to remember NOT to put it in front of exactly proper other things).
So I guess for me the most problematic Objective-C part is the one that has to do with C (because it adds a level of complexities on top of C). The "Objective" part is actually very nice, once you get used to the call syntax and the brackets.
Example: I find Russian very hard to speak. That doesn't mean Russian IS hard, I just don't know russian. And some languages are harder (more stuff to learn) than others.
So what makes Obj-C hard? For me, it was Apple's gigantic MVC-style framework. Rewiring my brain to grok Obj-C was nothing compared to grokking Foundation Kit, UIKit and AppKit. Growing up with C++, C# and Java, you get used to a particular way of doing thing. APIs are designed and interacted with in a certain way. Apple's API feel completely different. From building strings and making network connections to working with images and animations. Apple's version just feels different.
You seem to make a big case of the message passing syntax, but your example is very poorly chosen. Rather than 'performAction:withTwoParameters:' it should be 'performActionWithFirstParameter:andWithSecondParameter:' as are most Cocoa methods. Named parameters may seem verbose but they are much more readable than 'performAction(param1, param2)'.
If Objective C is a "large" language, I wonder what you'd call C++ or C#. Huge ? Humongous ? If you think Cocoa is large and complex, the C++ Standard Library or the Java library will make you weep.
UIKit view controller classes are also not flexible enough, and crap out in a lot of custom multithreaded operations when they shouldn't. I could reproduce the same behavior with my own classes (animations, transitions, view control, etc) using just basic UIView classes and it would work significantly better.
For instance, for the life of me I CANNOT get calls to NSNotificationFactory right the first try, and there are no compiler hint to help you...it just doesn't work for some reason.
There are other items like that. Not much help when the app crashes, lack of Namespaces (class name collisions), etc.
Then throw in all the fun of submitting an app to the store. Working with iAds and In App Purchases will make you want to hurt something.
Maybe it is because I am programming computers since the Z-80 days, or because like it is expected in my country I did a good earned CS degree.
If you think using a language like Objective-C is hard, maybe you should not be programming at all.
Building a great app is hard. Building and running a great service is hard. Building and running a great company is hard.
Most commonly used programming languages aren't hard.
Well, those people have fairly low expectations of themselves then. People say this bullshit about the supposedly strange Obj-C syntax, whereas the part that it's not C is basically 99% "Smalltalk in square brackets". Nobody complains that Smalltalk has a strange syntax, even small kids seem to use Squeak just fine.
[object performAction: param1 withTwoParameters: param2]
not that different to:
object.performAction(self, param1, withTwoParameters=param2)
in Python, or any language with named parameters. The syntactic differences are superficial. You don't even have to know about selectors and messages to understand the gist of what that invocation will do. "OMG, method parameters have a name" --well, big effin' deal.
Ever seen C++ (especially the recent standard)? Or the beast with 1000 features C# has become? Obj-C compared is leanness personified.
The ACTUAL source of complexity in programming in Objective-C is the huge Cocoa (et al) API. But a huge API, especially nicely documented as Cocoa is, and with such breadth and nice MVC design, is a GOOD THING.
This tightly-coupled codesign is unique to Objective-C. There are other languages that run on .Net, such as Iron Python. Lots of language use the JVM besides Java, like Clojure. Even Ruby and Rails are two distinct entities and projects. The only significant effort to use a different language with Cocoa/Cocoa Touch and the Objective-C runtime, Mac Ruby, was a project largely backed by Apple before they abandoned it.
Actually, there are several efforts besides MacRuby to use another language with the Objective-C runtime: Nu (Lisp like), F-script (Smalltalk like). But the main difference here is that the Objective-C runtime is a very simple runtime, not a full VM, so the comparison to CLR and Java is not that apt. For one, CLR was designed from the start to support multiple languages, and Java didn't have any major language targeting the VM until like 2004-5.
In general, not that good of an article...
[object performAction: param1 withTwoParameters: param2]
is roughly equivalent to object.performActionwithTwoParameters(param1, param2)Sure, but it's not like that distinction is really important for the programmer. For most intends and purposes, he can just think of those as keyword identifiers
--or, better, as a kind of keyword identifiers that also have to be present whenever referring to the method.
Not that big of a deal.
(I'll use lisp conventions, it's what I'm used to)
What you're saying is for coders, saying
(doit x y :withFloat 5 :key "string")
has no important distinctions with [foo doit:x:y withFloat:5 key:"string"]
But keywords have defaults if they're missing. And furthermore you can have them in any order. So to implement the equivalent of the Lisp method above, I'd have to implement all of the following methods in Objective-C doit::withFloat:key:
doit::key:withFloat:
doit::withFloat:
doit::key:
doit::
That's just for two keywords. What happens when you have ten?It's many things to many people. To beginners, its a friendly cub to play with. To enterprise coders its the beast of burden to carry things. To newbie web developers/existing c++ programmers its familiar face on a new road. It won't devour you unless you have a death wish.
I can't agree with this. Jython and Rhino started in 1997. JRuby started in 2001. Those are all ports of fairly major languages, and all saw significant use before 2004.
You do this so that you actually know what you're putting into the damn function. As soon as you've typed 'object per' Xcode's autocomplete will have filled out the rest of the entire function, complete with parameter descriptions and little empty bubbles with the expected argument class for you to tab over and type your arguments into. This is indispensable if you have a method with a large number of arguments.
P.S. My only experience with Objective-C is with the iOS SDK.
(...plus some extra runtime data, but you don't usually notice that.)
>Synthesizing properties
>Dot-syntax for accessing getters/setters
>Garbage Collection
>Blocks (closures)
>Automatic Reference Counting
>Weak references
Sorry, but none of these things make the language any simpler — they all add yet another style of doing things that only raises the bar and the learning curve for new developers when reading existing code, in precisely the same way that C++ and Perl have done. And this is true even of garbage collection (which, by the way, is deprecated in 10.8), because it needs to coexist with other frameworks and code that might not be garbage-collected, and more importantly because all heap-allocated C buffers consequently require their own low-level wrappers (e.g., NSAllocateCollectable, objc_memmove_collectable, etc.).
Also be aware, there is something called "Objective-C++" which is a superset of C++.
The syntax is not "weird" unless you just don't know the language. Acclimation is part of the learning process.
In my opinion, the syntax/language is pretty great. I enjoy ObjC greatly. My main beef with it is that it's less than portable. ObjFW attempts to solve this, and is a phenomenal framework already.