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:@"[email protected]"

        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

 

 

你可能感兴趣的:(objective)