Monday, May 25, 2009

iPhone dev Stupidity 11

* Sending message to nil.

In Objective-C it's safe to send message to nil - no runtime error, just some default behavior. 

   NSIndexPath * path = [table indexPathForSelectedRow];


   NSLog(@"path ref: %d, path %@", [path retainCount], path);


When path is nil, [path retainCount] will return 0 instead of triggering an error.


Sunday, May 24, 2009

iPhone dev Stupidity 10

* Memory management overkill.

Chapter 9, page 241. Why writing this:


when you can write it like:


The Beginning iPhone Development book prefer the former. But the later is clear, simple and more like c++ style of init.

Note: Refer the Stupidity 4  for why we must write controllers instead of self.controllers in the later one.

iPhone dev Stupidity 9

* Trying to load a mismatched class from NIB.

childController = [[DisclosureButtonController alloc] initWithNibName:@"DisclosureDetail" bundle:nil];


When the class in .nib file is assigned as DisclosureDetailController while trying to load it as DisclosureButtonController will definitely cause an error.

There's no runtime check. The error will be triggered when you trying to assign a non-existing property (which is in DisclosureButtonController but not in DisclosureButtonController.

Saturday, May 23, 2009

iPhone dev Stupidity 8

* a || b returns YES/NO

in Lua a or b returns a if a is not nil or it will return b.

While in Objective-C, || works the same with C - || produce a logic result.

Friday, May 22, 2009

iPhone dev Stupidity 7

* Mess with File's Owner

Beginning iPhone Development, Chap 8, page 207

When building a subclass in interface builder, we just want to load the .xib file later and grab the "CustomCell" cell object out of the array loaded.

If you mess the File's Owner to CustomCell (instead of the default NSObject) and mess with the IBOutlets, it will confuse the loader:

[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];

That Owner: argument is "The object to assign as the nib’s File's Owner object."

The mechanism is not clear now (didn't bother to read the Resource Programming Guide yet).

    


iPhone dev Stupidity 6

* View tag conflict


If you create a sub view with the same Tag of main view (0 as default), [cell.contentView viewWithTag:kNameValueTag] may return the wrong view.

Beginning iPhone Development, Chap8, page 200.


Thursday, May 21, 2009

iPhone dev Stupidity 5

* Choosing a @selector at runtime

Q: can this: (win ? @selector(playWinSound) : @selector(showButton)) be simplified?

A: No.  The simplified form:

@selector(win ? playWinSound : showButton)


won't compile. The @selector must be expanded by at compile time.

iPhone dev Stupidity 4





* Should there be a self for an ivar?

Beginning iPhone Development, Chap 7, page 166
Q: Could we omit that self in self.stateZips?

A: If it's omitted, the assignment is normal pointer alignment - the synthesized getter/setter will not be invoked here.

That is: the (retain, nonautomic)  will not applicable. After the [dict release], stateZips will also be gone.

-----

more explanation from Stack Overflow :

The assumption is that you shouldn't (usually) be accessing instance variables directly. Mostly this is because doing so circumvents the Key-Value Observing machinery in Cocoa. Rather, the expectation is that you'll access and mutate properties via getter/setter methods. 
...
The only time you should be accessing instance variables directly is in -init and -dealloc methods.

The reason the ivar should be used directly in these cases is beacuse the getter/setter may have side effects that depend on a fully initialized instance, thus making them dangerous in -init and -deallocwhere the state of the object is fully initialized. In all other cases, you should be using self.ivar (or[self ivar] and [self setIvar:newValue]).

-----

So the bare assignment stateZips = dict is the same with self->stateZips = dict - both walk around the generated getter/setter.

Q: How about the getter?
A: It's safe if you don't do extra works in the getter.

iPhone dev Stupidity III

* Create a new view controller in nib and forget to change the type from NSObject to proper class.















of course, you need to connect the view outlet too:



Wednesday, May 20, 2009

iPhone dev stupidity II

* Forget to connect view controller to the outlet of app delegate.


Till the chap 5 of Beginning iPhone Development, the Outlets need to take care of:

If you mistakenly left one or more outlets out, later a run-time error is there waiting.


Tuesday, May 19, 2009

iPhone dev stupidity - I

1. Disable user interaction for the View.

2. Forget to connect the outlet with IB control.

Friday, May 15, 2009

SPEL - the virtue

With SPEL (macro) "lets us write exactly what we want to say without a lot of fat- It's almost like we've created our own computer language just for creating game commands. Creating your own pseudo-language with SPELs is called Domain Specific Language Programming, a very powerful way to program very quickly and elegantly."





(casting SPEL to fool the compiler seeing a different form)

Code without a lot of fat will be DRY and it may also attack the essense of the problem to solve - it's like casting SPELs .



Back quotes embedding - List

Q: Explain the results:

A:
1. `(,@'(1 2))
,@ will expand the list follows it. '(1 2) is is evaluated to a list. so ,@ will expand it to 1 2 which will be inserted into the outer ( 1 2 ).

2. `(,@(1 2))
,@ will expand the list follows it. It meets (1 2) - a malformed function call which will yield an error.



Q: Now could you explain the GAME-ACTION macro from the Casting Spells in Lisp ?

Why there's an extra ' in ',',place?

A:
 
1. ',',place
it's because we want that extra ' to expand:
(game-action (weld chain bucket attic ...))
If you prefer to write:
 (weld 'chain 'bucket 'attic ...) 
instead of 
(weld chain bucket attic ...)
You can safely ignore that '.

2. ,@',rest
the rest is the extra conditions we'd like to add to the existing ones. A simple one is (cond t '(1)), and it will be expanded into:



Back quotes embeded: The basic

Q: Explain the results:

A: 
1. `(,'foo)  -> (FOO)
when evaluate a symbol 'foo, since there's no need to bind a variable, ,'foo will be FOO.

2. `(`(,'foo)) -> ('(FOO))
though embedded in the double backup quotes, it doesn't metter: 'foo is a symbol not a variable - it doesn't bothered to the binding thing.  

3. (let ((x 'foo)) `(`(,x))) -> (`(,x)) with a warning saying that x is never used
when the ,x is met in the 2nd level of data mode, that x doesn't need to be evaluated: it's a literal value, well formed, ready for the 2nd expanding.

4. (let ((x 'foo)) `(`(,',x))) -> ('(FOO))
when ,',x is met in the 2nd level of data mode, the ',x need to be resolved as a symbol (for that '). ,x will be evaluated at the 1st level where there's a binding (x 'foo).

So ,',x will be ,'FOO, then FOO. (see A 1.)

5. (let ((x 'foo)) `(`(,,x))) -> (`(,FOO))
when ,,x is met in the 2nd level embedding of data mode, the ,x after , will be evaluated - on the 1st level. ,x -> FOO, thus ,,x -> ,FOO.



Q: So the embedding affects the expanding?

A: Sure.

`(`(,',x))) => `(         ) ; 1st level, (x 'foo);        ,x evaluated here                
                 `(,',x))   ; 2nd level, () no binding; ,',x evaluated here


Q: one more level?

A: yeah:




The explanation is quite the same with previous one. But we can try a different approach:

It's the same with the above one. But with the lexical vairable factored out to show the levels.



Q: Why do we need that extra quote ' in the nested let?

A: Because we can't assign FOO directly to a variable. It need to be a symbol.

Thursday, May 14, 2009

Symbols are big - lexical variables

Ansi Common Lisp 8.5 Symbols and Variables

For a foo: 

(defun foo () '(1))
And evaluate:

A symbol used as a lexical variable is just a place holder: 

(symbol-name x) ; x is 'FOO

We can get name of 'x too: (symbol-name 'x) ; "X"

While other ops like (symbol-value 'x) and (symbol-function 'x) will yield error.

That's the difference between special variable and lexical variable: 
 * special variable will hold the symbol assigned to it
 * lexical variable will act as a place holder - only hold the name, and left the value-binding to the evaluator.


Symbols are big

Symbol structure from Chap 8 of Ansi Common Lisp.




So when a function FOO is defined, there will be a pair inserted into current package: <"FOO" 'FOO>, a string as function name and a symbol to hold the name, function object, package etc.

Unless FOO is in function call form (foo), you'll have to use symbol 'foo to reference it:

 When we set a variable to an old symbol, a new symbol is created and the value is set to the old symbol - kind of indirect pointers: