OC语言之核心语法

来源:互联网 发布:ubuntu语言包下载 编辑:程序博客网 时间:2024/05/01 11:21

一、NSString

NSString存在于Foundation框架中,用于定义字符串变量。

int main(){//定义字符串NSString *str = @”itcast”;//打印字符串使用%@占位符NSLog(@”%@”, str);return 0;}

stringWithFormat方法介绍:

int age = 15;int no = 5;NSString *str = [NSString stringWithFormat:@”age is %d, no is %d”, age, no];

length方法介绍:

NSString *str = @”jack”;int size = [str length];//返回str字符串的长度,返回类型为unsigned long类型NSLog(@”size is %d, str length is %ld”, size, [str length]);

NSString API文档:

XCode->Help->Documentation and API Reference->搜索“NSString

二、点语法

利用点语法替换set方法和get方法

Student *stu = [Student new];//[stu setAge:100];stu.age = 100; // 同上//int age = [stu age];int age = stu.age; // 同上

点语法的本质还是方法调用;

当使用点语法的时候,编译器会自动将点语法展开成相应的方法。

三、成员变量的作用域

@private: 只能在当前类的对象方法里访问(@implementation中默认是@private

@protected: 可以在当前类以及子类的对象方法中直接访问(@interface中默认是@protected

@public: 任何地方都能直接访问对象的成员变量

@package: 同一个体系内(框架内)可以访问,介于@private@public之间(很少用)


一、@property@synthesize

情况一:

@interface Person : NSObject{int _age;}@property int age;//生成_age的set和get方法的声明@end@implementation Person@synthesize age = _age; //实现名为age的property,并且访问名为_age的成员变量。如果写成“@synthesize age;”,则访问名为“age”的成员变量@end

情况二:

@interface Person : NSObject@property int age;//生成_age的set和get方法的声明@end@implementation Person@synthesize age = _age; //实现名为age的property,并且访问名为_age的成员变量,如果没有_age,则在@implementation中自动生成一个@private的成员变量@end

情况三:

@interface Person : NSObject@property int age;//生成_age的set和get方法的声明;生成@implementation中的property实现;生成@private的_age成员变量@end

情况三是最简洁的写法,但是缺点是生成的成员变量为@private的,所以继承的子类不拥有此成员变量,如果子类希望拥有,则如下写法:

情况四:

@interface Person : NSObject{int _age; //默认为@protected}@property int age;@end

如果代码如下时:

@interface Person : NSObject@property int age;@end@implementation Person- (void)setAge:(int)age{}- (int)age{}@end

不自动生成_age成员变量,因为setget实现已经存在,所以编译器认为不需要访问_age属性,所以不自动生成,此时的类中不存在_age这个成员变量。

五、id

idOC语言中的关键字,是一种类型,所以当自定义名称的时候,不可以取名为“id”。

id是万能指针,可以指向\操作任何OC对象。id中已经包含*

id相当于NSObject *

 

使用情况一:

指向对象,操作对象(包括字符串)

id d = [Person new];d.age = 10;int a = d.age;

使用情况二:

作为形参(或成员变量),意为可以传入任何对象(继承于NSObject),包括字符串,因为字符串是NSString类型的对象

void test(id d){}

六、构造方法(init

    用来初始化对象的方法,是个对象方法,“-”开头

 

Person *p = [Person new];

完整的创建一个可用的对象

1>分配存储空间 +alloc

2>初始化 -init

 

new方法内部会调用两个方法 +alloc-init

//new拆开://调用+alloc分配存储空间Person *p = [Person alloc];//调用-init进行初始化Person *p1 = [p init];//相当于:Person *p = [[Person alloc] init];//在@implementation中重写init方法@implementation- (id)init{  //重写构造方法的条件  //1.一定要调用super的init方法,意为初始化父类中的所有可继承的属性  if( self = [super init] ) //把父类的可继承属性赋值给self当前对象  {    //2.如果不为空(取决于OC运行时特性),开始初始化子类特有成员变量(此成员变量是包含在self中的)    _age = 10;  }  //返回self  return self;}@end

自定义构造方法:

1.一定是对象方法,一定以“-”开头

2.返回值一般是id类型

3.方法名一般以init开头

@interface Person : NSObject@property NSString *name;- (id)initWithName:(NSString *)name;- (id)initWithName:(NSString *)name andAge:(int)age;@end@implementation Person- (id)initWithName:(NSString *)name{  if(self = [super init])  {    _name = name;  }  return self;}- (id)initWithName:(NSString *)name andAge:(int)age{  if(self = [super init])  {_name = name;_age = age;  }  return self;}@end

自定义构造方法规范:

各自的成员变量在各自的类实现中赋值

- (id)iniWithName:(NSString *)name andAge:(int)age andNo:(int)no{  //将name、age传递到父类方法中进行初始化  if(self = [super initWithName:name andAge:age])  {    _no = no;  }  return self;}

七、分类(Category

    分类的好处,可以模块化开发,一个模块的功能放到一个分类中。在不改变原来类内容基础上,为类增加一些方法。

//分类名称:Person+MJ.h、Person+MJ.m#import “Person.h” // 导入Person类@interface Person (MJ)- (void) test;@end@implementation Person (MJ) // 一般MJ的位置写模块名- (void)study{}@end

使用注意:

1.只能增加方法,不能增加成员变量

2.分类方法实现中可以访问原来类中声明的成员变量

3.分类可以重新实现原来类中的方法,但是会覆盖原来的方法

4.方法调用的优先级:分类(最后参与编译的分类中的方法优先)-->原来类-->父类


八、类

类本身也是一个对象,是个Class类型的对象,简称类对象

所有类都是由Class创建的类对象,再由类对象创建类的对象

获取类对象:

1.Class c = [p class]; //p为对象

2.Class c = [Person class]; //Person为具体类

    

类对象的使用:

1.类对象 == 

2.类对象和类一样,可以调用类方法

3.内存中一个类只有一个类对象

 

类的加载和初始化

1.OC程序启动时,会加载所有类和分类,即调用所有类和分类的+(void)load方法,并且只调用一次(先加载父类,再加载子类)

2.当使用某个类时候,会先初始化其父类,然后初始化其自身,即先调用父类的+(void)initialize方法,然后调用自身的+(void)initialize方法

3.当使用某个类的时候,若其有分类,则调用分类中的+(void)initialize方法,而不调用自身的+(void)initialize方法。分类方法调用优先级最高


九、description方法

默认情况下,利用NSLog%@输出对象时,结果是:<类名:内存地址>

1.会调用对象的-description方法

2.拿到-description方法的返回值(NSString *)显示到屏幕上

- (NSString *)description{  return [NSString stringWithFormat:@”age is %d, name is %@”, _age, _name];}

十、SEL(运行时机制)

当内存中加载一个类后,类中会存在方法列表,罗列所有的对象方法和类方法。每一个方法的地址都对应着各自的SEL消息值。当调用方法时候,会首先将方法名封装成SEL数据,然后通过performSelector方法发送SEL数据,根据SEL值在类的方法列表中找到相应的方法,并执行。

1.把方法名包装成SEL类型的数据

2.根据SEL数据找到对应的方法地址

3.根据方法地址调用对应的方法

无参方法调用:

[p performSelector:@selector(test)];

有参方法调用:

[p performSelector:@selector(test) withObject:@”123”];

用字符串方式调用方法:

NSString *name = @”test”;SEL s = NSSelectorFromString(name);[p performSelector:s];

每个方法中都内置一个SEL对象“_cmd”,_cmd代表当前方法,打印_cmd如下:

-(void)test{  // _cmd == @selector(test);  NSString *str = NSStringFromSelector(_cmd);  NSLog(@”%@”, str);  // 打印为“test”,说明_cmd指向当前方法  [self performSelector:_cmd];  //会引发死循环}

消息就是SEL。

0 0
原创粉丝点击