ObjectiveC——类

Class的定义

1:调用系统的类

eg:

class  pointer to obejct   object

NSString   *message   = @"Hello";

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

 

注:在ObjectiveC中所有的类的实例都用指针表示

相比较普通变量实例存储的是内存里直接申请的空间,存储值本身,而object实例存储的是指针地址,指向类的object在内存的位置。

 

Define/Using Pointer

NSString   *message;  //define pointer

message  = @"Hello";  //use pointer

eg:

View Code
 1 #import <Foundation/Foundation.h>
 2 
 3 void myFunction(NSString *foo);  {
 4      //定义NSString的指针作为参数
 5     NSLog(@"The message was %@", foo);    
 6     //使用指针不需要写*,pointer的placeholder是%@
 7 }
 8 
 9 int main(int argc, const char * argv[])
10 {
11     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
12     NSString * message = @"Hello";    
13     //定义一个指向NSString的指针
14     
15     myFunction(message);    //使用指针不需要写*
16     [pool drain];
17     return 0;
18 }

 

Call Object's methord

1: Normal Methord Call

c#          myObject.someMethord(arg);

ObjectiveC  [myObject someMethord:arg];

 

 

c#          myObject.insertString("Hello", 11);

 

ObjectiveC  [myObject insertString: @"Hello" atIndex:11];  //each parameter is named

eg:

 

1 [NSFileManager replaceItemAtURL:
2     withItemAtURL:
3     backupItemName:
4     options:
5     resultingItemURL:
6     error:
7 ];

 

2: Nested Methord Call

[myObject someMethord:[anotherObject anotherMethord]];

Class Methord VS Instance Methord

 

View Code
 1 NSString *message = @"Hello";
 2 MSString *message2 = [message uppercaseString];
 3 //uppercaseString是Instance Methord,需要从一个object call
 4 //uppercaseString的返回值是一个指针,所以要返回给一个新的指针
 5 
 6 NSLog(@"The result is %@", message2);
 7 
 8 //注:调用methord需要用[]框起来
 9 
10 NSDate *myDate = [NSDate date];
11 //[NSDate date]是class methord直接使用,不需要一个object承载
12 NSLog(@"The date is %@", meDate);

 

 

 Creating an Object

New Methord:

 

new方法创建object的三步过程:(注:所有的class都有new方法)

 

 

  1. Allocation:ObjectiveC到内存里挖出一块object大小的空间
  2. Initialization:对object进行初始化Variable
  3. Return:返回object的地址到指针变量(myDate)

 

拆写new:(为什么要拆开? 因为init有多种不同的初始化方法,new只有一种初始化方式)

实际工作中我们经常分开实现new的功能:

  1. NSDate ×myDate = [NSDate alloc];  1:创建了一个NSDate的对象, 2:返回指向这个对象的指针
  2. myDate = [myDate init];  对象初始化步骤,set variables

实际上我们可以合并写成一句:

NSDate *myDate = [[NSDate alloc] init];

 

eg:

 

Class *myObj = [[Class alloc] init];
Person *fred = [[Person alloc] init];
Dog *fido = [[Dog alloc] init];
Customer *acmeCorp = [[Customer alloc] init];
NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];

 

 Memory Management

1:Release now

使用拆分发或者new方法创建的object,你拥有该object,记得使用完后要release。 Iphone Ipad app和2011年前创建的Mac App都需要清除不用的memory。

NSDate *myDate = [[NSDate alloc] init];

......  //use NSDate object

double seconds = [myDate timeIntervalSince1970];

//使用完后

[myDate release];   //清除不用的内存

myDate = nil;      //清除不用的指针(不是必须要写)

 

还有什么方法关键词代表用户清除Memory的责任?

alloc, new, retain, copy

 我们使用alloc一次,需要release一次,retainCount计数从1->0.

我们做了init,和三次retain,retainCount为4,我们需要清除四次使retainCount回0

 

 2:AutoRelease:

[fred autorelease];  //把这个object放到release pool里

...  //some times in future一次清除pool

[pool drain];  //程序自动调用release

3: When to use autorelease?

你创建一个类可以创建对象并返回

createEmployee{

  //create a new object

  Employee *fred = [[Employee alloc] init];

  [fred autorelease];

  return fred;

}  //谁调用这个class创建对象,那么就是他的责任去release 他创建的内存

 

创建自定义类

相关知识:

ObjectiveC里class分成两个file:interface, implementation

interface .h file: 描述class都有什么methord,有什么变量,什么是aviable的。

implementation .m file:Real code of class

 

1:New->File

2:Objective-C class


3:选择所创建子类的继承类,这里是NSObject:(NSObject是super父类,任何类都是继承它的)

4:Employee类创建成功

分成两个file的好处是,很多情况我们看apple的源代码,我们只要看.h就可以知道class是做什么用的。

不象其他语言需要写class关键字,ObjectiveC的class就是@interface和@impelemntation

 

 5:实例

.h

View Code
 1 #import <Foundation/Foundation.h>
 2 
 3 @interface Employee : NSObject
 4 
 5 @property NSString *name;
 6 @property NSData *hireDate;
 7 @property int employeeNumber;
 8 //分别定义了类的三个data,即三个property
 9 
10 -(void) someMethord;    //定义该类的behivor,即方法。 返回类型要加()。 "-"代表这个类是instance class
11 
12 @end

.m

View Code
 1 #import "Employee.h"
 2 
 3 @implementation Employee
 4 
 5 @synthesize name, hireDate, employeeNumber; //Xcode自动为三个变量generate了两个方法,get; set;
 6 
 7 -(void) someMethord{
 8     NSLog(@"In the methord");
 9 }
10 @end

main.m 调用我们自己的class

View Code
 1 #import <Foundation/Foundation.h>
 2 #import "Employee.h"    //import自己的project file用“”
 3 
 4 int main(int argc, const char * argv[])
 5 {
 6 
 7     @autoreleasepool {
 8         
 9         // insert code here...
10         Employee *fred = [[Employee alloc]init];  //alloc和init方法虽然我们没定义但是都继承自NSObject
11         [fred someMethord];
12     }
13     return 0;
14 }

6:补充

 

View Code
.h文件

#import <Foundation/Foundation.h>
@interface Person : NSObject
@end



.m文件

#import "Person.h"
@implementation Person
-(id)init
{
self = [super init];
if(self){
//Initialization code here  
}
return self;
}
@end

 

我们可以看到,Xcode自动为我们加载一些代码,并以文件名为类名。@interface Person : NSObject;

在@interface关键字后的就是类名。

 

 

 自创的方法

概念:任何方法都是为一个类而创建的,ObjectiveC的方法分为两类,实例的方法和类的方法。前者用“-”表示,需要实例化一个实例才可以用,后者用“+”表示,不需要实例化在类的范围内使用。

 

带参数方法的定义:

  • 类的返回类型:如(void), (Bool), (NSObject *)
  • 方法名用camal记法
  • 方法的参数可以有多个,除了第一个参数,后面每个参数都由两部分组成,前半部分是方法名的延续,后一部分是参数名,之间用“:”分开
  • 记得后半部分的参数用“()”表示数据类型

  单个parameters

  - (int) timesTen    (int) param;

  -(NSString *) createMessage : (NSString *) input;  //函数接受一个NSString指针并返回一个NSString指针

 

  多个parameters

  -(int)   addNumberz    :   (int) a        toNumber             :        (int) b; 

   methord name:   param type + name 2nd part methord name: param type + name

 

Instance Methord的创建:

 

-(int) addNumberz: (int) a  toNumber: (int) b;

或者:

-(BOOL) sendEmailTo:(NSString *)paramTo
        withSubject:(NSString *)paramSubject
    andEmailMessage:(NSString *)paramEmailMessage{
// Send the email and return an appropriate value

   if([paramTo length]==0 || [paramSubject length]==0 || [paramEmailMessage]==0){
      //one or some of the parameters are empty
      NSLog(@"Empty parameter is/are provided.");
      return NO;
      }
   return YES;
}

 

这是一个instance methord(-),返回值是(BOOL). 方法名是 sendEmailTo : withSubject : andEmailMessage, 有三个参数,call function in this way.

[self   sendEmailTo:@"someone@somewhere.com"
        withSubject:@"My Subject"
    andEmailMessage:@"Please read my email."];

 

Class Methord的创建:

创建一个allocAndInit在class里,可以同时达到allocate and initialize对象并返回对象给他的caller

View Code
//This is MyClass.h

#import <Foundation/Foundation.h>
@interface MyClass : NSObject

+(id) allocAndInit

@end

//Implement the Class Methord, this is MyClass.m
#import "MyClass"
@implementation MyClass
+(id) allocAndInit{
    MyClass *result = [[MyClass alloc] init];
    return result;
}
@end

 In our app delegate we can use this class methord to allocate and initialize an instance of MyClass.

//this is AppDelegate.m file

#import
"AppDelegate.h" #import "MyClass.h" @implementation AppDelegate @synthesize window = _window; -(BOOL)         application:(UIApplication *)application    didFinishLaunchingWithOption:(NSDictionary *)launchOptions{
   MyClass
*instance1 = [MyClass allocAndInit]; NSLog(@"Instance 1 = %@", instance1); self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];   self.window.backgroundColor = [UIColor whiteColor];   [self.window makeKeyAndVisible];   return YES; }

 

3:

.h

 

1 #import <Foundation/Foundation.h>
2 
3 @interface MyClass : NSObject
4 
5 -(void) performAction: (int) param;
6 -(int) addNumber: (int) a toNumber: (int) b;
7 
8 @end

 

.m

 1 #import "MyClass.h"
 2 
 3 @implementation MyClass
 4 
 5 -(void)performAction:(int)param{
 6     NSLog(@"You passed in the value %i", param);
 7 }
 8 
 9 -(int)addNumber:(int)a toNumber:(int)b{
10     return a+b;
11 }
12 
13 @end

自创的变量

这里我们定一个instance变量,该变量只能这个类内部调用,如果我们要别的文件也可以访问这个变量,我们需要创建get;set方法

.h

 1 @interface Player : NSObject
 2 {
 3     //instance variables
 4     int score;  //所有需要定义的变量写在{}里
 5 }
 6 
 7 -(int) score;    //getter
 8 -(void) setScore: (int) amount;    //setter
 9 
10 @end

.m

 1 @implementation Player
 2 // accessor methord
 3 -(int) score{
 4        return score;
 5 }
 6 
 7 -(void) setScore : (int) amount{
 8     score = amount;      
 9 }
10 
11 @end

 

 

自创的属性

上面通过get;set方法访问instance 变量有些麻烦,我们可以用property来替代,property会自动创建get;set方法

上述代码替换成property简化多了

.h

 

 1 @interface Player : NSObject
 2 {
 3     //instance variables
 4     int score;  //所有需要定义的变量写在{}里
 5 }
 6 @property int score;  //同样type和name的property会自动wrap上面的score
 7 
 8 @end

 

.m

 

 1 @implementation Player
 2 @synthesize score;
 3 
 4  
 5 @end

 

随着xcode的升级4.4+,定义property更简单了:

 

.h  是public face of class

 

 

 1 @interface Player : NSObject2 @property int score;  3 
 4 @end

 

 

.m  如果还要定义instance variable供class内部使用,{var1, var2}加在@implementation下面

 

 

 1 @implementation Player
 2
 3 @end

 

 

 

property是有自己的属性的:

@property (strong) NSString * firstName;  //strong reference to NSString *:We own it, as long as we use ARC will take care it

@property (readonly) int * employeeID;    //just synthesize a getter methord

 

关于property和variable的总结:

  1. interface .h 只放property 和方法的声明
  2. implemtation .m 放内部使用的变量,和方法的具体实现

.h的结构

 

 1 @interface Player : NSObject
 2 
 3 //各种property的声明,property可以带自己的属性
 4 @property int score;  
 5 @property (strong) NSString * firstName
 6 ...
 7 
 8 //各种方法的声明
 9 //methords
10 ...
11 
12 @end

 

.m的结构

 1 @implementation Player
 2  3      //各种内部var的定义
 4      int year;
 5      float speed;
 6      ....
 7 }
 8 
 9 //各种方法的具体实现
10 //-methord
11 
12 @end

 

Initializers

MyClass *myObj = [[MyClass alloc] init];

//所有的类都有init方法,因为继承自NSObject

 

custom init:

在Xcode我们可以从snipy里拉出一个init看看

.m

 

#import "MyClass.h"

@implementation MyClass

- (id)init  //代表可以返回任何object
{
    self = [super init];  //self相当于this,本object自己,super代表NSObject,调用其init方法
    if (self) {
        <#initializations#>  //如果self存在则这里就是我们需要custom的init代码段
     score = 5000
} return self; } @end

 

.h

#import <Foundation/Foundation.h>

@interface Player : NSObject

@property int score;

@end

main.m

#import <Foundation/Foundation.h>   //调用apple的API就<>
#import "Player.h"    //调用本项目里的文件就""

int main(int argc, const char * argv[]){
  @autoreleasepool{
     //insert code here...
    Player * p = [[Player alloc] init];
    NSLog(@"The score is %i", p.score)  
  }
  return 0;
}

这就是ObjectiveC的init,相对于C#里的构造函数: 这里总是有alloc,regular init,和more custom init methods(看下NSData下有很多不同

-init methord,分别对应不同的参数或者返回值的初始化函数)

.m

 

#import "MyClass.h"

@implementation MyClass
- (id)initWithInt : (int) s  //NSObject里没有我们这个custom的init名字,所以我们要在.h里声明
{
    self = [super init];  //self相当于this,本object自己,super代表NSObject,调用其init方法
    if (self) {
        <#initializations#>  //如果self存在则这里就是我们需要custom的init代码段
     score = s
} returnself; }
- (id)init  //因为这时默认NSObject的init方法,所以.h里不用声明
{
    self = [super init];  //self相当于this,本object自己,super代表NSObject,调用其init方法
    if (self) {
        <#initializations#>  //如果self存在则这里就是我们需要custom的init代码段
     score = 5000
} return self; }

} @end

 

.h

 

#import <Foundation/Foundation.h>

@interface Player : NSObject
- (id)initWithInt : (int) s  //我们需要做这一步,因为我们initWithInt在别的file里调用的时候是可见的 @property
int score; @end

 

main.m

 

#import <Foundation/Foundation.h>   //调用apple的API就<>
#import "Player.h"    //调用本项目里的文件就""

int main(int argc, const char * argv[]){
  @autoreleasepool{
     //insert code here...
    Player * p = [[Player alloc] init];
    NSLog(@"The score is %i", p.score);
   Player *x = [[Player alloc] initWithInt: 7500];
   NSLog(@"The Scroe value is %i", [x score]);  //换成x.score也可以
}
return 0; }

最后如果一个init方法包含了另外一个我们可以简单写:

 

#import "MyClass.h"

@implementation MyClass
- (id)initWithInt : (int) s  //NSObject里没有我们这个custom的init名字,所以我们要在.h里声明
{
    self = [super init];  //self相当于this,本object自己,super代表NSObject,调用其init方法
    if (self) {
        <#initializations#>  //如果self存在则这里就是我们需要custom的init代码段
     score = s
} returnself; }
- (id)init  //因为这时默认NSObject的init方法,所以.h里不用声明
{
    return [self initWithInt:5000];
}

} @end

 

 

posted @ 2012-09-13 00:46  若愚Shawn  阅读(859)  评论(0编辑  收藏  举报