OC语言之核心语法

一、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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值