Any way I can disable 'message to nil not throwing an error' behavior (i.e. I want the error)? - objective-c

I've read that sending messages to nil is allowed in ObjC and I understand that this is a part of the language and that there has been controversy about it, pro and con. I don't want to open up a discussion about any of that.
I just want to know if there is a way, short of always having to test if (presumedInstance != nil), that I can get errors when trying to send a message to nil? It is not helping me when coding that I don't get errors - makes it harder to determine where the code flaw is, etc.
Perhaps a setting or script in XCode?

No, there's no way to do this. In fact, it's a very important feature of Objective-C. I'd actually argue it's more important for you to do the testing (if (object), which is the same as if (object != nil)) because it forces you to consider the inputs and outputs of your functions and methods, and the code paths your application goes through. It might be frustrating at first, but it's one of the things you get used to, and it makes life much easier.

What about trying assertions, like with NSAssert?
NSAssert Generates an assertion if a given condition is false.
Usage : NSAssert(condition, desc)
Parameters :
condition : An expression that evaluates to YES or NO.
desc : An NSString object that contains an error message describing the failure condition.
Reference :
What's the point of NSAssert, actually?
Apple Developer Documentation

Related

objective-c difference between x.y and [x y]? [duplicate]

I am going through some walkthroughs fpr Objective-C and I got to many places where I raised my eyebrows. I would love to get them down.
Is there a fundamental difference in message sending and method calling? Objective-C lets me do both: object.message yields the same result as [object message]. I think maybe nested messages cannot be created using the dot operator strategy?
I created an NSArray object, now I am about to print results for this using an NSEnumerator:
id myObject = [object objectEnumerator];
in a while loop iterating and printing results. The type of myObject is id, which means it's resolved at runtime and not compile time. I know very clearly what kind of objects are stored in my NSArray—they are NSStrings—so by changing the type of myObject to
NSString * myObject, it works just fine. However, I experimented and found out that myObject can be of any type, be it NSString or NSArray or NSEnumerator, and any of these work just fine, perfectly iterating the NSArray object and yielding the same results.
What's up with that?
I'm not sure what kind of distinction you're trying to make between "message sending" and "method calling", since they're two ways of describing the same thing. The dot syntax is just a shortcut for calling getters and setters, that is:
[foo length]
foo.length
are exactly the same, as are:
[foo setLength:5]
foo.length = 5
You should generally only use the dot syntax when you're using getters and setters; use the square bracket syntax for all of your other method calls.
For your second question: this is how dynamic typing works. Any type declarations you put in your code are hints to the compiler; your Objective-C method calls will always work as long as the objects respond to them.
It's a distinction oriented at the person reading your code. Dot syntax indicates state (I'm accessing an ivar), method syntax indicates behavior (I'm performing some action). To the runtime, both are the same.
I think Apple's intention is to show accessors as an implementation detail you shouldn't worry about. Even when they could trigger side effects (due to some additional code in the accessor), they usually don't, so the abstraction is imperfect but worth it (IMHO). Another downside of using dot notation is that you don't really know if there is a struct or a union behind it (which unlike message sending, never trigger side effects when being assigned). Maybe Apple should have used something different from a dot. *shrugs*
I think maybe nested messages cannot be created using the dot operator strategy?
Dot notation can be used to nest calls, but consider the following:
shu.phyl.we.spaj.da
[[[[[shu]phyl]we]spaj]da]
In this case, the uglier, the better. Both are a code smell because one object is creating dependencies to another object far far away, but if use brackets to pass messages you get that extra horrible syntax from the second line, which makes the code smell easier to notice. Again, convention is to use dots for properties and brackets for methods.
1: Your terminology is incorrect. The dot operator is not "method calling", a different operation. It's just a different visual appearance for message sending. There's no difference between [x y] and x.y. The dot syntax can only take one argument though, as it's intended to be used only for property access.
2: The static (compile-time) type of an object has no effect on its behavior at runtime. Your object is still an NSEnumerator even if you're calling it something else.
1) They're both message sending, just different syntax. [object message] is traditional syntax, object.message is the "dot notation", but means exactly the same thing. You can do some kinds of nesting with dot notation, but you can't do anything with methods that take complex arguments. In general, old hand Obj-C programmers don't use dot notation except for simple accessor calls. IMHO.
2) The runtime is really smart and can figure it out on the fly. The type casting of pointers is really just a clue to the compiler to let you know when you messed up. It doesn't mean a thing (in this case) when the message is sent to the array to fetch a value.
Message sending is the preferred way of doing this. It's what the community uses and reinforces the concept of objects sending messages to one another which comes into play later when you get into working with selectors and asking an object if it responds to a selector (message).
id is basically a pointer to anything. It takes some getting used to but it's the basis for how Objective-C handles dynamic typing of objects. When NSLog() comes across the %# format specifier, it sends a description message to the object that should should replace the token (This is implemented in the superclass NSObject and can be overridden in the subclass to get the desired output).
In the future when you're doing this, you might find it easier to do something like this instead:
for (NSString *s in YourNSArrayInstance) //assuming they are NSStrings as you described
{
NSLog(#"%#", s);
}
Or even simply just:
for (NSString *s in YourNSArrayInstance) //assuming they are NSStrings as you described
NSLog(#"%#", s);
You'll learn to like message sending eventually.

Is it kosher to use NSNull category trick in order to avoid [NSNull performSelector:...] problems?

In our project, we occasionally get our iPhone app to crash when there is something on the network returns JSON with nil in it. Of course, we do have a helper class, which takes care of problems like that. However, people are error-prone and do call objectForKey on NSDictionary instead of our own stringForKey or dateForKey etc.. Now, there is a class to kill all problems like that, once and for all: https://github.com/nicklockwood/NullSafe
My question is: Is NullSafe is really safe? Because sometimes you do want your program to crash if the logic is wrong and you get NSNull. Just ignoring the problem hides it. The app probably will not crash, but, in some cases, will do something weird.
Now I am leaning towards not using this class and just making sure that our JSON NSDictionaries is filtered of all NSNulls BEFORE we try to parse get the values (It could affect performance though).
What do you guys think?
That class is safe in terms of not crashing the application when you send some message to it. It behaves much like nil value.
This class does not solve bugs! If you may get NSNull you should act as it is there and handle that case.
Once I used such class (also because of JSON), but I put NSLog (or ratcher breakpoint) into the -forwardInvocation: method to see from where and why it was called. I wouldn't use this in production.
You also asked about performance. Not sure what takes more: removing NSNulls from an array or searching all classes for their method signatures ;)

Is asserting that every object creation succeeded necessary in Objective C?

I have recently read Apple's sample code for MVCNetworking written by Apple's Developer Technical Support guru Quinn "The Eskimo!". The sample is really nice learning experience with what I guess are best development practices for iOS development.
What surprised me, coming from JVM languages, are extremely frequent assertions like this:
syncDate = [NSDate date];
assert(syncDate != nil);
and this:
photosToRemove = [NSMutableSet setWithArray:knownPhotos];
assert(photosToRemove != nil);
and this:
photoIDToKnownPhotos = [NSMutableDictionary dictionary];
assert(photoIDToKnownPhotos != nil);
Is that really necessary? Is that coding style worth emulating?
If you're used to Java, this may seem strange. You'd expect an object creation message to throw an exception when it fails, rather than return nil. However, while Objective-C on Mac OS X has support for exception handling; it's an optional feature that can be turned on/off with a compiler flag. The standard libraries are written so they can be used without exception handling turned on: hence messages often return nil to indicate errors, and sometimes require you to also pass a pointer to an NSError* variable. (This is for Mac development, I'm not sure whether you can even turn exception handling support on for iOS, considering you also can't turn on garbage collection for iOS.)
The section "Handling Initialization Failure" in the document "The Objective-C Programming Language" explains how Objective-C programmers are expected to deal with errors in object initialization/creation: that is, return nil.
Something like [NSData dataWithContentsOfFile: path] may definitely return nil: the documentation for the method explicitly says so. But I'm honestly not sure whether something like [NSMutableArray arrayWithCapacity: n] ever returns nil. The only situation I can think of when it might is when the application is out of memory. But in that case I'd expect the application to be aborted by the attempt to allocate more memory. I have not checked this though, and it may very well be that it returns nil in this case. While in Objective-C you can often safely send messages to nil, this could then still lead to undesirable results. For example, your application may try to make an NSMutableArray, get nil instead, and then happily continue sending addObject: to nil and write out an empty file to disk rather than one with elements of the array as intended. So in some cases it's better to check explicitly whether the result of a message was nil. Whether doing it at every object creation is necessary, like the programmer you're quoting is doing, I'm not sure. Better safe than sorry perhaps?
Edit: I'd like to add that while checking that object creation succeeded can sometimes be a good idea, asserting it may not be the best idea. You'd want this to be also checked in the release version of your application, not just in the debug version. Otherwise it kind of defeats the point of checking it, since you don't want the application end user to, for example, wind up with empty files because [NSMutableArray arrayWithCapacity: n] returned nil and the application continued sending messages to the nil return value. Assertions (with assert or NSAssert) can be removed from the release version with compiler flags; Xcode doesn't seem to include these flags by default in the "Release" configuration though. But if you'd want to use these flags to remove some other assertions, you'd also be removing all your "object creation succeeded" checks.
Edit: Upon further reflection, it seems more plausible than I first thought that [NSMutableArray arrayWithCapacity: n] would return nil rather than abort the application when not enough memory is available. Basic C malloc also doesn't abort but returns a NULL pointer when not enough memory is available. But I haven't yet found any clear mention of this in the Objective-C documentation on alloc and similar methods.
Edit: Above I said I wasn't sure checking for nil is necessary at every object creation. But it shouldn't be. This is exactly why Objective-C allows sending messages to nil, which then return nil (or 0 or something similar, depending on the message definition): this way, nil can propagate through your code somewhat similar to an exception so that you don't have to explicitly check for nil at every single message that might return it. But it's a good idea to check for it at points where you don't want it to propagate, like when writing files, interacting with the user and so on, or in cases where the result of sending a message to nil is undefined (as explained in the documentation on sending messages to nil). I'd be inclined to say this is like the "poor man's" version of exception propagation&handling, though not everyone may agree that the latter is better; but nil doesn't tell you anything about why an error occurred and you can easily forget to check for it where such checks are necessary.
Yup. I think it's a good idea.. It helps to filter out the edge cases (out of memory, input variables empty/nil) as soon as the variables are introduced. Although I am not sure the impact on speed because of the overhead!
I guess it's a matter of personal choice. Usually asserts are used for debugging purpose so that the app crashes at the assert points if the conditions are not met. You'd normally like to strip them out on your app releases though.
I personally am too lazy to place asserts around every block of code as you have shown. I think it's close to being a bit too paranoid. Asserts might be pretty handy in case of conditions where some uncertainity is involved.
I have also asked this on Apple DevForums. According to Quinn "The Eskimo!" (author of the MVCNetworking sample in question) it is a matter of coding style and his personal preference:
I use lots of asserts because I hate debugging. (...)
Keep in mind that I grew up with traditional Mac OS, where a single rogue pointer could bring down your entire machine (similarly to kernel programming on current systems). In that world it was important to find your bugs sooner rather than later. And lots of asserts help you do that.
Also, even today I spend much of my life dealing with network programs. Debugging network programs is hard because of the asynchrony involved. Asserts help to with this, because they are continually checking the state of your program as it runs.
However, I think you have a valid point with stuff like +[NSDate date]. The chances of that returning nil are low. The assert is there purely from habit. But I think the costs of this habit (some extra typing, learning to ignore the asserts) are small compared to the benefits.
From this I gather that asserting that every object creation succeeded is not strictly necessary.
Asserts can be valuable to document the pre-conditions in methods, during development, as design aid for other maintainers (including the future self). I personally prefer the alternative style - to separate the specification and implementation using TDD/BDD practices.
Asserts can be used to double-check runtime types of method arguments due to the dynamic nature of Objective C:
assert([response isKindOfClass:[NSHTTPURLResponse class]]);
I'm sure there are more good uses of assertions. All Things In Moderation...

Why the macros in Objective-C / Cocoa?

I'm coming from a place without macros (Java/Python/C#/Scala) so perhaps my perspective is distorted but...
Why are macros used in Cocoa? Two that spring to mind are NSLocalizedString and NSAssert (and STAssert). Would it be so hard / unsuitable to make them functions (which could be inlined)? I suppose I find them a little bizarre as an unnecessary throw-back to C (and yes, I am familiar with the pedigree of Obj-C).
Is it just something that was done back in the day or is there a specific reason?
In general it is preferable to avoid macros, but for functionality like that provided by NSAssert(), you can't.
If you look at the definition, you'll see that it uses __LINE__, __FILE__, _cmd and self from the context it is used in. If it wasn't a macro, it wouldn't have access to that information.
For NSLocalizedString however, i see no obvious reason.
NSLocalizedString is a convenience macro and could probably be made a function.
However, there are good reasons why NSAssert and friends are macros besides the one given in Georg's answer. NSAssert evaluates a boolean expression to determine whether an exception should be thrown. That boolean expression might be quite computationally expensive and not the sort of thing you want to happen in your release code. There's no mechanism in C (and therefore Objective-C) of omitting normal function calls for a release build without resorting to the preprocessor or perhaps using stuff like:
if (debug)
{
assertAsAFunction(foo == 3, "foo should be 3");
}
Another advantage of the NSAssert macro is that the condition can be stringified for use in a log message.

Returning errors in objective-c

Im newish to objective-c and am starting to wonder what is the common/standard/proper way for handling and catching errors?
It seems like it might be possible to use NSError to do this, is that a good idea or a hijack of cocoa?
I'm pretty sure that's what the NSError class is there to do - give details about errors. The most common pattern you'll see is a method that takes a pointer to an NSError object, as in:
- (id)doSomethingWithArgument:(id)arg error:(NSError **)error
The method returns some value (or possibly nil) for the result of doing something, but if the call failed will place an NSError object at the pointer passed with details about the failure. Your documentation is responsible for specifying what gets returned if the method does encounter an error.
The other method that comes to mind is the #throw-#catch block; however, in Objective-C #throwing an exception can be rather computationally expensive, and it's usually only recommended to do so in truly exceptional situations.
Edit: wow, turns out a lot of people have really strong opinions about #throwing exceptions. To sum up the (quite helpful) commentary on the issue:
Throwing exceptions should most often deal with programmer error (situations that should never happen, and the like); exceptions should not be used for ordinary error handling. Instead, use the error method demonstrated above or post instances of NSNotification.
If you do wind up making extensive use of #throw/#catch blocks, be very careful about the logic surrounding them. Objective-C provides a lot of ways to detach methods to run in other threads, or delay execution, etc. Be very careful to account for all those possibilities when you write your code.
Finally, another very valid point:
If you do use the error object passed to a method, the return value should indicate it. Don't try to do both (return a partially valid object and set the error object).