This is more of a puzzle than anything else, but it will test your understanding of function pointer (and, by extension, block pointer) declarations. Consider the following declaration:
int (*(*myFunctionPointer)(int (*)(int))) (int);
What (in words) is myFunctionPointer?
Rewrite the HelloObjectiveC program from Chapter 4, "Your First Objective-C Program," to use an NSInvocation:
Instead of passing the Greeter the greeting text as an NSString, create a Greeting class that encapsulates the greeting and a method that issues the greeting. (The method should take the greeting string as an argument and log it.)
Package up issuing the greeting as an NSInvocation and pass it to the Greeter.
The Greeter should then issue the greeting by sending the invocation object the -invoke message.
Write a program that uses some simple blocks and verify for yourself that:
- The value for an ordinary automatic value that a block sees is fixed when execution passes over the block literal, and is unchanged if the value of the variable is changed later in the code.
- A block cannot modify the value of an ordinary automatic variable in its scope.
- A block can both read and set a variable declared with the __block type modifier.
Rewrite the program in Listing 16.1 to use a block instead of a function. Use the NSMutableArray method:
NSComparator is a typedef for a pointer to a block that takes two object arguments and returns the same integer constants as the function in Listing 16.1.
Write a program that looks for a name in an array of names and reports back the name's index in the array:
- Create an NSArray with some names (use NSString objects).
- Create a local NSString variable to hold the name you are searching for and an integer block variable to report back at what index the name was found.
- Search the array using -enumerateObjectsUsingBlock:.
- Make sure your block uses the stop argument to stop looking when the name is found.
- If the name you are looking for isn't in the array, the block variable holding the index should have a value of -1.
Write a program that uses the ObjectWithName class (see Listings 16.3 and 16.4):
- Add a logging statement to ObjectWithName's dealloc routine.
- In your main program, allocate an instance of ObjectWithName.
- Release the object and verify that it is never deallocated.
- Make the fix suggested in the text and verify that the object now deallocates.