objective-c revisited

global and static variables

To make a variable global, you declare it outside of a particular function.

#include <stdio.h>
#include <stdlib.h>

//declare a global variable
float lastTemperature;

a static variable is like a global variable in that it is declared outside of any function. However, a static variable is only accessible from the code in the file where it was declared.

//declare a static variable in main.c
static float lastTemperature;

//initialize to 50 degrees
static float last = 50.0;

stylish pointer declaration

what do you think these are?

float* b, c;

Surprise! b is a pointer to a float, but c is just a float;

Putting the * directly next to the variable name makes this clearer.

float *b,*c;

when the caller wants two parts return?

#include <stdio.h> 
#include <math.h> 
 
int main(int argc, const char * argv[]) 
{ 
    double pi = 3.14; 
    double integerPart; 
    double fractionPart; 
 
    // Pass the address of integerPart as an argument 
    fractionPart = modf(pi, &integerPart); 
 
    // Find the value stored in integerPart 
    printf("integerPart = %.0f, fractionPart = %.2f\n", integerPart, fractionPart);  
 
    return 0; 
} 

 Pass by reference

void cartesianToPolar(float x, float y, float *rPtr, float *thetaPtr) 

That is, when the function is called, it will be passed values for x and y. It will also be supplied with locations where the values for radius and theta can be stored.

 

void cartesianToPolar(float x, float y, double *rPtr, double *thetaPtr) 
{ 
    // Store the radius in the supplied address 
    *rPtr = sqrt(x * x + y * y);
    ...
    // Store theta in the supplied address 
    *thetaPtr = theta;
}

 Avoid dereferencing NULL

Sometimes a function can supply many values by re ference, but you may only care about some of them. How do you avoid declaring these variables and passing thei r addresses when you’re not going to use them anyway? Typically, you pass NULL as an address to tell the function “I don’t need this particular value.”
This means that you should always check to make sure the pointers are non-NULL before you dereference them.

 Struct

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


//Most of the time, you use a structure declaration over and over again. So it’s common to create a typedef for the structure type. 
//A typedef defines an alias for a type  declaration and allows us to use it more like the usual data types.
// Here is the declaration of the type Person 
typedef struct { 
    float heightInMeters; 
    int weightInKilos; 
} Person; 

Person person; 

 Simple Heap usage

#include <stdio.h> 
#include <stdlib.h> 
 
typedef struct { 
    float heightInMeters; 
    int weightInKilos; 
} Person; 
 
float bodyMassIndex(Person *p) 
{ 
  return p->weightInKilos / (p->heightInMeters * p->heightInMeters); 
} 
 
int main(int argc, const char * argv[]) 
{ 
    // Allocate memory for one Person structure 
    Person *x = (Person *)malloc(sizeof(Person)); 
 
    // Fill in two members of the structure 
    x->weightInKilos = 81; 
    x->heightInMeters = 2.0; 
 
    // Print out the BMI of the original Person 
    float xBMI = bodyMassIndex(x); 
    printf("x has a BMI of = %f\n", xBMI); 
 
    // Let the memory be recycled 
    free(x); 
 
    // Forget where it was 
    x = NULL; 
 
    return 0; 
}

 Foundation

Command Line Tool, Type:Foundation,

#import <Foundation/Foundation.h> 
 
int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
 
         NSDate *now = [NSDate date]; 
         NSLog(@"The new date lives at %p", now);
         NSLog(@"The new date lives at %@", now);   
  
    } 
    return 0; 
}

%p prints out the location of the object.

%@ prints out the description of the object.

 

Instance variable to properties

#import <Foundation/Foundation.h> 
 
// The class Person inherits all the instance variables 
// and methods defined by the class NSObject 
@interface Person : NSObject 
{ 
    // It has two instance variables 
    float heightInMeters; 
    int weightInKilos; 
} 
 
// You will be able to set those instance variables using these methods 
- (void)setHeightInMeters:(float)h; 
- (void)setWeightInKilos:(int)w; 
 
// This method calculates the Body Mass Index 
- (float)bodyMassIndex;  
@end 

Apple has created a handy way to simplify writing accessor methods called properties. With a property, you can declare both the setter and getter methods in one line.

 

#import <Foundation/Foundation.h> 
 
@interface Person : NSObject 
{ 
    float heightInMeters; 
    int weightInKilos; 
} 
@property float heightInMeters; 
@property int weightInKilos;  
 
- (float)bodyMassIndex; 
@end
#import "Person.h" 
 
@implementation Person 
 
@synthesize heightInMeters, weightInKilos; 
 
- (float)bodyMassIndex 
{ 
    return weightInKilos / (heightInMeters * heightInMeters); 
} 
 
@end

 

Retain cycle

In a parent-child relationship, the general rule for preventing this type of retain cycle is the parent owns the child, but the child should not own the parent.

What if you want a collection of floats or int s or pointers to structures? You can wrap co mmon C primitive types in an object. There are 

two classes that are designed sp ecifically for this purpose. NSNumber holds C number types. NSValuecan hold a pointer and some types of structs. You are not allowed to add nil to any of the collection classes we have covered. What if you need to put that idea of nothingness, a “hole, ” into a collection? There is a class called NSNull .

 

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.

 

In a project, it used to be pretty common to include a collection of headers in every file of code. This led to clutter at the beginning of your file and made compiles take longer. To make life easier and compiles faster, most Xcode projects have a file that lists headers to be precompiled and
included in every file. In your project, this file is called XXX-Prefix.pch .

 

Constant

#import <Foundation/Foundation.h> 
 
int main (int argc, const char * argv[]) 
{ 
    @autoreleasepool { 
 
        NSLog(@"\u03c0 is %f", M_PI); 
        NSLog(@"%d is larger", MAX(10, 12)); 
 
        NSLocale *here = [NSLocale currentLocale]; 
        NSString *currency = [here objectForKey: NSLocaleCurrencyCode ]; 
        NSLog(@"Money is %@", currency); 
 
    } 
    return 0; 
}

When the class NSLocale was written, this global variable appeared in two places. In NSLocale.h , the variable was declared something like this:

 

extern NSString const *NSLocaleCurrencyCode;

The const means that this pointer will not change for the entire life of the program. The extern means “I promise this exists, but it will be defined in some other file.” And sure enough, in the file NSLocale.m , there is a line like this:

NSString const *NSLocaleCurrencyCode = @"currency";

 

posted on 2012-05-31 09:10  grep  阅读(296)  评论(0编辑  收藏  举报