Skip to main content

The concepts in Objective-C

The digest  from book 'Learning Objective-c 2.0" and http://qs4int.blogspot.ca/2013/01/v-behaviorurldefaultvmlo.html

# Expressions and Statements
Expressions and statements in C are the equivalent of phrases and sentences in a natural
language. When you add a semicolon (;) to the end of an expression, it becomes a statement.

Expression  could be: a+10
Statement could be: int v  = a+10;
Other example like:
if ( expression )
statement1
else
statement2

for (expression1; expression2; expression3) statement

#Pointers
A pointer is a variable whose value is a memory address. It points to a location in memory.


#typedef
The typedef declaration provides a means for creating aliases for variable types:
typedef float Temperature;
Temperature high, low;

#define
#define is used for textual replacement. The most common use of #define is to define
constants, such as:
#define MAX_VOLUME 11

# Preprocessor directives
#include and #import do essentially the same thing: request that the preprocessor read a file and add it
to its output. Usually, you are including a file of declarations (a .h file), and those declarations are used
by the compiler to understand the code it is compiling.
What is the difference between #include and #import? #import ensures that the preprocessor only
includes a file once. #include will allow you to include the same file many times. C programmers tend
to use #include. Objective-C programmers tend to use #import.



#const
The const keyword tells the compiler that a variable should be considered as constant.
The compiler flags any attempt to change the variable as an error:
const int maxAttempts = 100;

maxAttempts = 200; // This will cause a compiler error.

#Define  a Class

@interface className : superclassName
{
Instance variable declarations
}
Method declarations
@end

@interface and @end are used to mark the beginning and end of the interface
section. Objective-C words that begin with an @ character are compiler directives,
instructions to the compiler, not executable code.

@interface is followed by the class name, a colon, and the name of the class’s
superclass.

The class’s instance variable declarations go between a set of curly brackets, following
the @interface line.

The class’s methods are declared following the instance variable declarations.

#Runtime
Objective-C requires a runtime. The runtime is a dynamic link library of C functions
that is provided on all systems that support Objective-C. It does the work of setting up
and operating the Objective-C messaging system. The runtime does its work silently,
behind the scenes.

#Message Expressions
The most important addition that Objective-C makes to C is the message expression:
[receiver message]
The receiver is an object or, strictly speaking, a pointer to an instance of a class. The
message is the name of one of the methods defined by the receiver’s class plus any arguments
that the method takes.

When a statement containing a message expression is executed,
the Objective-C runtime determines the receiver’s class and looks up the method
name contained in message in the class’s list of methods and executes the code corresponding
to that method.

#id
id is a type that holds a “pointer to object.” A variable that is declared as id can hold a
pointer to any Objective-C object, independent of the object’s class.

Notice that there is no asterisk in this declaration. id implies the asterisk.

The declaration:
id myObject;
tells you (and the compiler) myObject is a pointer to an object. e.g.
NSString* string1 = @"The Big Apple";
id something;
something = string1;

There is no need for an asterisk (*):
id *myObject; // WRONG !

#nil
nil is a defined constant that represents a “pointer to no object.” While nil is defined
to be zero, it is universally used instead of the bare zero whenever an object pointer to
nothing is required.

In Objective-C, send messages to a receiver whose value is nil will do nothing and execution continues with the next line of code.

#SEL
the name of the method to be executed.

SEL is a type that holds a representation of an Objective-C method name(message). SEL is short
for selector. Method names are sometimes called selectors because the runtime uses them to
select the block of code to execute in response to a message.

SEL aSelector = @selector( aMethodName );

# Methods
The structure of an Objective-C method is very similar to that of a C function (in fact,
the compiler eventually turns the methods into C functions). There are three major differences:
#1 Methods are executed on behalf of a particular instance of the class that defines
them.  The method receives a pointer to the object instance in the form of the hidden variable self. (“Hidden” means you can use the variable self in the method even though it is not declared in the method’s argument list or anywhere else.)
#2  Methods can directly access the object’s instance variables without having to declare them.
#3 The syntax for naming the method and its arguments is different from that of a function.


Method Name Conventions
It is not a formal part of the Objective-C language specification, but it is an almost universal
naming convention in Objective-C that each part of a method name begins with a
lowercase letter, and that any subsequent words in that part of the name begin with
capital letters, like this:

- (void) setOutlineColor:(NSColor*) outlineColor
fillColor:(NSColor*) fillColor;

The comma and ellipsis are not part of the name. The name of the preceding method is:setOutlineColor:fillColor:

#Messaging

Asking an Objective-C object to execute one of its methods is not the same thing as
calling a function. Function calls are usually statically bound: What happens at runtime is
determined at compile time. When the compiler encounters a function call, it inserts a
jump instruction into the code that makes up the function body. Objective-C uses a
more dynamic system called messaging. When you want an Objective-C object to execute
one of its methods, you send the object a message. The object responds by executing the
method that corresponds to the message.
A message expression has the following form:
[receiver message]

The message expression is enclosed in square brackets. The receiver is the object that will
execute a method. It receives the message. The message is the name of the method that
you want the receiver to execute, plus any arguments that the method takes.

How does this work? When you execute a message expression, the Objective-C runtime
examines the receiver and determines its class. The runtime has a table for each class that
lists the methods that the class defines and associates the name of each method with a
pointer to the code that implements the method. The runtime takes the method name
from the message, finds the corresponding pointer in the receiver’s class table, and then
uses the pointer to execute the method’s code.

n Objective-C, nil is the zero pointer.  If you send a message to nil, the return value doesn’t mean anything.

#Abstract Classes
An abstract class is a class that is intended to be used as a template for subclassing. You do not normally create an instance of an abstract class.

#Destroying Objects
How do you get rid of objects when you are finished with them? It is important to
properly dispose of unneeded objects so their bytes can be returned to the heap for
reuse. In Objective-C, you don’t explicitly destroy object

If you are using reference counting, when you are finished with an object you created
or retained, you send it a release message. If that release message drops the object’s
retain count to zero, the release method calls the object’s dealloc method. The object’s
dealloc method should:
1. Send a release message to any objects that the disappearing object has created or
retained.
2. Invoke the superclass’s dealloc method.
The dealloc method for the TeeShirt from the preceding section class looks like:
- (void) dealloc
{
[shirtColor release];
[super dealloc]; // Important!
}

#Class Methods
Class methods are methods defined on a class’s class object. Another way of saying this is
that the class object (or the class name), not an instance of the class, is the receiver for a
message corresponding to a class method. Here are the rest of the details:
n The declaration of a class method begins with a plus sign. For example, the declaration
of alloc is:
+ (id) alloc

#Fast Enumeration
The basic form of a for ... in loop is:
for ( type loopVariable in expression )
{
statements
}

e.g. for ( NSString* path in pathsToList )

#Multiple @catch Blocks
You can set up your code to throw different types of exception objects for different situations.
Then, you can use multiple @catch blocks, each typed for a different type of
exception object, with a single @try block, as shown in the following example:
@try
{
...
}
@catch (NSString* myString)
{
// Process exceptions thrown with an object that is an
// NSString or a subclass of NSString
}
@catch (NSException *myException)
{
// Process exceptions thrown with an NSException object
}
@finally
{
...
}

#Categories
Categories let you add methods to an existing class without subclassing it and without
requiring access to the class’s source code. Using a category to extend the behavior of a
class is a much lighter-weight procedure than subclassing.

e.g.
NSString+CamelCase.h
#import <Foundation/Foundation.h>
@interface NSString (CamelCase)
-(NSString*) camelCaseString;
@end

#Should I Use a Category or a Subclass?
If a category method will do the job, use it. Lengthening the

inheritance chain of a class can make the code more difficult to maintain.

#@property and @synthesize
The @property statement provides a shorthand way to declare accessor methods. So developers don't need to declare setter and getter method from the @interface
The @synthesize statement causes the compiler to write the designated accessor methods for you.

@property (nonatomic, readonly) int employeeNumber;
@property (nonatomic, retain) NSString *name;

@synthesize employeeNumber;
@synthesize name;




#Function Pointers
The general form of a function pointer is:
return_type (*name)(list of argument types);

The asterisk tells you the variable is a pointer.
e.g. int (*myFunctionPtr) (int);
e.g. myFunctionPtr( 5 ); // Execute the function through the pointer

#Blocks
Block in other language is also called anonymous functions.

Blocks are similar in many ways to functions, with the important exception that blocks
have direct access to variables in their surrounding context. “Direct access” means that a
block can use variables declared in its surrounding context even though those variables
are not passed into the block through an argument list. Blocks are declared as follows:

^(argument_list){ body };

Blocks begin with a caret (^), followed by an argument list enclosed in parentheses and
one or more statements enclosed in curly brackets. This expression is called a block literal,
and is defined as follows:
# Blocks can return a value by using a return statement in the body.
# You don’t have to specify the return type; the compiler determines the return type
by looking at the body of the block.

Block Pointers
A variable that is a block pointer (a pointer to a block) is declared as follows:
return_type (^name)(list of argument types);
This should look familiar; it has exactly the same form as the declaration of a function
pointer, except that the * has been replaced with a ^.

The following example illustrates how to declare a block pointer, assign a block to it, and
then call the block through the block pointer:
int (^doubler)(int); // doubler is typed as a pointer to a block
doubler = ^(int n){ return n*2; };
int j = doubler( 9 ); // j is now 18

or in one step:
int j = ^(int n){ return n*2; }( 9 ); // j is now 18

Block Variables
Variables declared with the new type modifier __block are called block variables:
__block int integerBlockVariable;

Block variables are visible to, and are shared and mutable by, any block defined in their
scope.

Blocks in Cocoa
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock: ^(void){ doSomething; } ];

NSArray *array =

[NSArray arrayWithObjects: @"dagger", @"candlestick",
@"wrench", @"rope", nil];

void (^loggingBlock)(id obj, NSUInteger idx, BOOL *stop) =
^(id obj, NSUInteger idx, BOOL *stop)
{ NSLog( @"Object number %d is a %@",
idx, [obj description] ); };

[array enumerateObjectsUsingBlock: loggingBlock];

^{
NSLog(@"I'm a log statement within a block!");
}

#Protocol
A protocol is a defined set of methods that a class can choose to implement. Protocols
are useful when an object needs to talk to one or more other objects but doesn’t know
(or particularly care) the class of those other objects.

#Delegate
Delegate is the class object, which will have definition of protocol. A delegate allows one object to send messages to another object when an event happens. For example, if you're downloading data from a web site asynchronously using the NSURLConnection class.

NSURLConnection has three common delegates:
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
- (void)connection:(NSURLConnection *)connection didReceiveResponse: (NSURLResponse *)response

# UIViewcontrollers'  Life Cycle:

ViewDidLoad - Called when you create the class and load from xib. Great for initial setup and one-time-only work
ViewWillAppear - Called right before your view appears, good for hiding/showing fields or any operations that you want to happen every time before the view is visible. Because you might be going back and forth between views, this will be called every time your view is about to appear on the screen
ViewDidAppear - Called after the view appears - great place to start an animations or the loading of external data from an API.
ViewWill/DidDisappear - Same idea as the WillAppear.
ViewDidUnload/Dispose - This might be trigger by didMemoryWarning method. In objective-c, this is where you do your cleanup and release of stuff, but this is handled automatically so not much you really need to do here.

#frame and bounds 
The frame of a view is the rectangle, expressed as a location (x,y) and size (width,height) relative to the superview it is contained within.The bounds of a view is the rectangle, expressed as a location (x,y) and size (width,height) relative to its own coordinate system (0,0).


# weak and  strong
strong is the default. An object remains “alive” as long as there is a strong pointer to it.
weak specifies a reference that does not keep the referenced object alive. 

A weak reference is a pointer that does not imply ownership.A weak reference is set to nil when there are no strong references to the object. 

#copy, retain, assign
copy Makes a copy of an object, and returns it with retain count of 1. If you copy an object, you own the copy. This applies to any method that contains the word copy where “copy” refers to the object being returned.

retain Increases the retain count of an object by 1. Takes ownership of an object. 

assign - "Specifies that the setter uses simple assignment. This is the default. You typically use this attribute for scalar types..." So you can imagine assigning a float

#Object Ownership and ARC
When an object has an object instance variable, the object with the pointer  is said to own the object that is being pointed to. From the other  end of things, an object knows how many owners  it currently has.

#Pass by reference
That is, you supply an address (also known as “a reference”), and

the function puts the data there.

double integerPart;
double fractionPart;
// Pass the address of integerPart as an argument

fractionPart = modf(pi, &integerPart);
..
*integerPart = xxx

another  example,
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:NULL
error:&error];

comments: In  java, all objects are passed by reference.


#NSArray
NSArray holds a list of pointers to other objects.

When an object is added to the collection, the collection establishes a pointer to the object, and the
object gains an owner.
When an object is removed from a collection, the collection gets rid of its pointer to the object, and
the object loses an owner.

#Sorting
There are several ways to sort an array, but the most common way is to use an array of sort descriptors.sort descriptor has the name of a property
of the objects contained in the array and whether that property should be sorted in ascending or
descending order.
e.g.
NSSortDescriptor *voa = [NSSortDescriptor sortDescriptorWithKey:@"valueOfAssets"
ascending:YES];
NSSortDescriptor *ei = [NSSortDescriptor sortDescriptorWithKey:@"employeeID"
ascending:YES];
[employees sortUsingDescriptors:[NSArray arrayWithObjects:voa, ei, nil]];



# Filtering
NSPredicate is the class for filtering. A predicate contains a statement that might be true.
i.e.
NSArray has a method that creates a new array that contains all the objects that satisfy the predicate:
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate

#Callbacks
In a real-world application, there needs to be an object that waits for events like mouse movements,
touch events, timers, and network activity. On Mac OS X and iOS, this object is an instance of
NSRunLoop. The run loop sits and waits, and when something happens, it sends a message to another
object.
We say that when something happens, the run loop causes a callback to occur. For Objective-C programmers, there are three forms that a callback can take. (Because these are very general ideas,
here use x for “a specific something” that happens.
#1Target- action: Before the wait begins, you say “When x happens, send this particular message to that
particular object.” The object receiving the message is the target. The selector for the message is the
action.
e.g.
Logger *logger = [[Logger alloc] init];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 target: logger selector:@selector(sayOuch:) userInfo:nil repeats:YES];

After 2 seconds when timer  finished, it will send message(sayOuch) to target(logger), which will invoke
that method afterwards.

#2 Helper objects: Before the wait begins, you say “Here is a helper object that conforms to your
protocol. Send it messages when things happen.” Helper objects are often known as delegates or data sources.


#3  Notifications: There is an object called the notification center. Before the wait begins, you say to
the notification center “This object is waiting for these sorts of notifications. When one of those
notifications arrives, send the object this message.” When x happens, an object posts a notification to
the notification center, and the center forwards it on to your object.

#C String (char *)
A C string is just a bunch of characters right next to each other in memory. The string ends when the
character 0x00 is encountered.

#struct and typedef
// Here is the declaration of the struct
struct Person {
float heightInMeters;
int weightInKilos;

};

struct Person mikey;
mikey.heightInMeters = 1.7;
mikey.weightInKilos = 96;

In struct, we call the related data 'members'.

Most of the time, you use a struct declaration over and over again. So it is common to create a typedef for the struct type. A typedef defines an alias for a type declaration and allows you to use it more like the usual data types.

// Here is the declaration of the type Person
typedef struct {
float heightInMeters;
int weightInKilos;
} Person;

struct Person mikey;
Person mikey;
mikey.heightInMeters = 1.7;

#the stack and heap
Every function has a stack frame where its local variables are stored. This memory is automatically allocated when a function starts  and automatically deallocated when the function ends. In fact, local variables are  sometimes called automatic variables because  of this convenient behavior.

Sometimes, however, you need to claim a  contiguous chunk  of memory yourself- a buffer(a long lie of bytes of memory). The buffer comes from a region of memory known as the  heap.

On the heap, the buffer is independent of any function's frame. Thus, it can be used across many functions. You request a buffer of memory using the function malloc(). When you are done using the buffer, you call the function free() to release your claim on that memory and return it to the heap.

e.g.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, const char * argv[])
{
// Declare a pointer
float *startOfBuffer;
// Ask to use some bytes from the heap
startOfBuffer = malloc(1000 * sizeof(float));
//startOfBuffer stayes in the stack. It is a pointer to the address of the first floating point number in the buffer.

// ...use the buffer here...
// Relinquish your claim on the memory so it can be reused
free(startOfBuffer);
// Forget where that memory is
startOfBuffer = NULL;
return 0;
}

#Sorting arrays

Arrays often require sorting. Immutable arrays cannot be sorted, but mutable ones can. There are several ways to sort an NSMutableArray. The most common is using the NSMutableArray method:
- (void)sortUsingDescriptors:(NSArray *)sortDescriptors;
The argument is an array of NSSortDescriptor objects

A sort descriptor has the name of a property of the objects contained in the array and whether that property should be sorted in ascending or descending order. e.g.
NSSortDescriptor *voa = [NSSortDescriptor sortDescriptorWithKey:@"valueOfAssets"
ascending:YES];
NSSortDescriptor *eid = [NSSortDescriptor sortDescriptorWithKey:@"employeeID"
ascending:YES];
[employees sortUsingDescriptors: @[voa, eid]];

#Filtering
When you filter a collection, you compare its objects to a logical statement to get a resultant collection
that only contains objects for which the statement is true.
A predicate contains a statement that might be true, like “The employeeID is greater than 75.” There is a class called NSPredicate. NSMutableArray has a handy method for discarding all the objects that do not satisfy the predicate:
- (void)filterUsingPredicate:(NSPredicate *)predicate;
With NSArray, you cannot remove objects that do not match the predicate. Instead, NSArray has a method that creates a new array that contains all the objects that satisfy the predicate:
- (NSArray *)filteredArrayUsingPredicate:(NSPredicate *)predicate;

#Preprocessor directives
Compiling a file of C, C++, or Objective-C code is done in two passes. First, the preprocessor runs
through the file. The output from the preprocessor then goes into the real compiler. Preprocessor
directives start with #, and the three most popular are #include, #import, and #define.

#Key-value observing
Key-value observing is a technique that lets you get a notification when a particular  property of an object changes. Essentially, you tell an object, “I want to watch your fido property. If it changes, let me know.” When the setFido: method gets called, you will get sent a message from the object you are observing: “Hey, my fido property has a new value.”













Comments

Popular posts from this blog

Quicksort implementation by using Java

 source: http://www.algolist.net/Algorithms/Sorting/Quicksort. The divide-and-conquer strategy is used in quicksort. Below the recursion step is described: 1st: Choose a pivot value. We take the value of the middle element as pivot value, but it can be any value(e.g. some people would like to pick the first element and do the exchange in the end) 2nd: Partition. Rearrange elements in such a way, that all elements which are lesser than the pivot go to the left part of the array and all elements greater than the pivot, go to the right part of the array. Values equal to the pivot can stay in any part of the array. Apply quicksort algorithm recursively to the left and the right parts - the previous pivot element excluded! Partition algorithm in detail: There are two indices i and j and at the very beginning of the partition algorithm i points to the first element in the array and j points to the last one. Then algorithm moves i forward, until an element with value greater or equal

Live - solving the jasper report out of memory and high cpu usage problems

I still can not find the solution. So I summary all the things and tell my boss about it. If any one knows the solution, please let me know. Symptom: 1.        The JVM became Out of memory when creating big consumption report 2.        Those JRTemplateElement-instances is still there occupied even if I logged out the system Reason:         1. There is a large number of JRTemplateElement-instances cached in the memory 2.     The clearobjects() method in ReportThread class has not been triggered when logging out Action I tried:      About the Virtualizer: 1.     Replacing the JRSwapFileVirtualizer with JRFileVirtualizer 2.     Not use any FileVirtualizer for cache the report in the hard disk Result: The japserreport still creating the a large number of JRTemplateElement-instances in the memory        About the work around below,      I tried: item 3(in below work around list) – result: it helps to reduce  the size of the JRTemplateElement Object        

Stretch a row if data overflows in jasper reports

It is very common that some columns of the report need to stretch to show all the content in that column. But  if you just specify the property " stretch with overflow' to that column(we called text field in jasper report world) , it will just stretch that column and won't change other columns, so the row could be ridiculous. Haven't find the solution from internet yet. So I just review the properties in iReport one by one and find two useful properties(the bold  highlighted in example below) which resolve the problems.   example: <band height="20" splitType="Stretch" > <textField isStretchWithOverflow="true" pattern="" isBlankWhenNull="true"> <reportElement stretchType="RelativeToTallestObject" mode="Opaque" x="192" y="0" width="183" height="20"/> <box leftPadding="2"> <pen lineWidth="0.25"/>