Hillegass Chapter 26 - why if(error)?

Discussion in 'Mac Programming' started by John Baughman, Aug 26, 2009.

  1. John Baughman macrumors member

    Joined:
    Oct 27, 2003
    #1
    I have copied the code in question from this page below.

    Why do we have the if(error) statement inside of if(match). Won't error always be a valid object? I see that it is NULL, which makes me also ask, when it would be anything other than NULL?

    Code:
    - (BOOL)isPartialStringValid:(NSString*)partial 
    			newEditingString:(NSString**)newString 
    			errorDescription:(NSString**)error
    {
    	//Zero-length strings are ok
    	if([partial length] == 0){
    		return YES;
    	}
    	
    	NSString *match =[self firstColorKeyForPartialString:partial];
    	if(match){
    		return YES;
    	} else {
    		if(error){   //WHY IS THIS IF STATEMENT HERE
    			*error = @"No such color";
    			
    		}
    		return NO;
    	}
    }
    

    Why not just, which works as well...

    Code:
    - (BOOL)isPartialStringValid:(NSString*)partial 
    			newEditingString:(NSString**)newString 
    			errorDescription:(NSString**)error
    {
    	//Zero-length strings are ok
    	if([partial length] == 0){
    		return YES;
    	}
    	
    	NSString *match =[self firstColorKeyForPartialString:partial];
    	if(match){
    		return YES;
    	} else {
    		*error = @"No such color";
    		return NO;
    	}
    }
    
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    error is a pointer to an NSString *, which could be nil, er... null? It's a pointer to something that's not an Object, so maybe null? Either way, it may be the address 0. If it is nil/null, trying to dereference it will not be a good time for anyone. As such, the code checks if a non-nil pointer was passed in, and if so sets its value (which is also a pointer) to the address of an NSString literal.

    -Lee
     
  3. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #3
    To be blunter, if I call your version like this:

    Code:
    [someObject isPartialStringValid:aString
    			newEditingString:anotherString
    			errorDescription:NULL];
    
    it will crash your app. Not so in Hillegass's version.
     
  4. petron macrumors member

    Joined:
    May 22, 2009
    Location:
    Malmo, Sweden
    #4
    John,

    Answer to your question: Just to confirm with CatFish_man & Lee - Yes, it will crash when error == 0. It is just a necessary sanity check.


    My short question since you are just a head of me going through the Hillegass book.
    Did you make the challange at the end of chapter 24 ? How does it work ?
    I would like to ask you to verify some of the behaviour if it is possible.

    You can even find my posting on this list. (Hillegass Chapter 24 chellange)

    /petron
     
  5. John Baughman thread starter macrumors member

    Joined:
    Oct 27, 2003
    #5
    Thanks for the quick responses Lee.

    OK, I understand why we are testing error, but I don't understand why we need to test it in this instance. You gave the example of you calling my method with errorDescription:NULL. This tells me that I still do not have my brain wrapped around subclass implementation as I do not understand why you would call this method.

    Please correct me where I go astray. As I understand it, isPartialStringValid:newEditingString:errorDescription: is an instance method of the NS Formatter Class and we are using it in a subclass implementation. So the method is invoked only when the user presses a key while the colorFormatter textField has the keyboard focus.

    This implies to me that only the system would ever invoke this method. If this is true, aren’t we guaranteed that error will always point to a pointer to a valid address?

    Hmmmm... I think I may have answered my own question. I see now that it is entirely possible for this to happen if, for example, we run out of memory.

    I am not trying to be nit picky here. I am only trying to make sure I understand what all is going on.

    Thanks,

    John
     
  6. Catfish_Man macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #6
    In this particular case, yes, the system should always call it with a valid error pointer. In many related cases (the NSError** final argument is a common idiom, and getting more common), the method is intended to be called by non-framework code, and lazy people like me will often not bother doing detailed error handling (i.e. we'll just check for failure, and not bother passing an NSError to find out exactly what failed).

    So it's more of a best-practices thing than an actual necessity for this example.
     
  7. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #7
    I guess I would say that it's best to always be safe about sanitizing your inputs, even if you think you/the system/other users of your code would never pass something unexpected to your function. Even if it is never called with bad parameters, on modern hardware a jne or whatever on your specific platform isn't going to be that costly. Also, you should value your time highly. Writing code that won't fail in an unexpected way will save you a lot of time in the long run.

    In this specific case, as Catfish_Man stated, the runtime code should never call your code "incorrectly", but you didn't really provide the background on what was going on with this function, so it was answered from the point of view of doing things "right" and applying rigor.

    -Lee
     
  8. John Baughman thread starter macrumors member

    Joined:
    Oct 27, 2003
    #8
    Thanks. Sorry. I have to remember in the future that this is not a forum on the book and will probably be getting help from folks who are not reading or even have the book and so probably do not know the full context of a question on a specific page or challenge.

    Thanks to everyone who replied. This exercise was produced one of those ahh ha! moments for me.

    John
     

Share This Page