OC--特有语法



一、 NSString

1、简单使用
NSStirng *str = @ Hello ;
char *name = "itcast";
NSLog(@"我在%@上课", str);


2、 length方法算的是字数,包括空格
NSString *name = @"哈哈jack";
int size = [name length];
长度是6
3、创建OC字符串的另一种方式
  NSString *newStr = [NSString stringWithFormat:@"My age is %d and no is %d and name is %@", age, no, name];


二、点语法
   点语法的本质还是方法调用。

    Person *p = [Person new];
   
    p.age = 10; // [p setAge:10];
   
    int a = p.age; // [p age];

三、成员变量作用域

@public : 在任何地方都能直接访问对象的成员变量
@private : 只能在当前类的对象方法中直接访问(@implementation中默认是@private)
@protected : 可以在当前类及其子类的对象方法中直接访问  (@interface中默认就是@protected)
@package : 只要处在同一个框架中,就能直接访问对象的成员变量

@interface和@implementation中不能声明同名的成员变量

四、自动生成getter和setter方法

1、@property:可以自动生成某个成员变量的setter和getter声明及实现

@property int age;


2、@synthesize自动生成age的setter和getter实现,并且会访问_age这个成员变量,如果不存在,就会自动生成_age变量
@synthesize age = _age;

默认会访问age这个成员变量,如果没有age,就会自动生成@private类型的age变量
@synthesize age; 

3、在代码中可以直接写@property 系统会自动生成get和set方法的声明及实现,而已可以生成下划线开头的@private类型的成员变量。
    

五、id
万能指针,能指向\操作任何OC对象
 id  == NSObject * 
id内已内置一个*,不能在后面写个*
id d = [Person new];


六、构造方法

1、构造方法:用来初始化对象的方法,是个对象方法,-开头
重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值

重写构造方法的注意点
1.先调用父类的构造方法([super init])
2.再进行子类内部成员变量的初始化


2、 剖析
 Person *p = [Person new];
 完整地创建一个可用的对象
 1.分配存储空间  +alloc
 2.初始化 -init
     
 1.调用+alloc分配存储空间
   Person *p1 = [Person alloc];
 2.调用-init进行初始化
   Person *p2 = [p1 init];
    
Person *p = [[Person alloc] init];

 3、重写init方法
//- (id)init
//{
//    // 1.一定要调用回super的init方法:初始化父类中声明的一些成员变量和其他属性
//    self = [super init]; // 当前对象 self
//   
//   
//    // 2.如果对象初始化成功,才有必要进行接下来的初始化
//    if (self != nil)
//    { // 初始化成功
//        _age = 10;
//    }
//   
//    // 3.返回一个已经初始化完毕的对象
//    return self;
//}

七、自定义构造方法
自定义构造方法的规范
1.一定是对象方法,一定以 - 开头
2.返回值一般是id类型
3.方法名一般以initWith开头

声明:
父类中
- (id)initWithName:(NSString *)name andAge:(int)age;
子类中
- (id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no;

实现:
父类中
- (id)initWithName:(NSString *)name andAge:(int)age
{
    if ( self = [super init] )
    {
        _name = name;
        _age = age;
    }
    return self;
}


  
子类中
 父类的属性交给父类方法去处理,子类方法处理子类自己的属性
- (id)initWithName:(NSString *)name andAge:(int)age andNo:(int)no
{
    // 将name、age传递到父类方法中进行初始化
    if ( self = [super initWithName:name andAge:age])
    {
        _no = no;
    }
   
    return self;
}



创建对象
 Student *p = [[Student alloc] initWithName:@"Jim" andAge:29 andNo:10];



八、分类
在不改变原来类模型的前提下,给类扩充一些方法, 2 种方式
>继承
>分类

分类的作用:在不改变原来类内容的基础上,可以为类增加一些方法
使用注意:
1.分类只能增加方法,不能增加成员变量
2.分类方法实现中可以访问原来类中声明的成员变量
3.分类可以重新实现原来类中的方法,但是会覆盖掉原来的方法,会导致原来的方法没法再使用
4.方法调用的优先级:分类(最后参与编译的分类优先) --> 原来类  --> 父类

格式
>分类的声明
@interface 类名 (分类名称)
// 方法声明
@end
>分类的实现
@implementation 类名 (分类名称)
// 方法实现
@end

好处
>一个庞大的类可以分模块开发
>一个庞大的类可以由多个人来编写,更有利于团队合作  

九、类的本质
1.类也是个对象
>其实类也是一个对象,是Class类型的对象,简称“类对象”
>Class类型的定义
typedef struct objc_class *Class;
>类名就代表着类对象,每个类只有一个类对象

2.+load和+initialize
     1.当程序启动时,就会加载项目中所有的类和分类,而且加载后会调用每个类和分类的+load方法( 不管程序运行过程有没有用到这个类)。只会调用一次。

     2.当第一次使用某个类时 (比如创建对象等),就会调用当前类的+initialize方法, 一个类只会调用一次

     3.先加载父类,再加载子类(先调用父类的+load方法,再调用子类的+load方法)


   先初始化父类,再初始化子类(先调用父类的+initialize方法,再调用子类的+initialize方法)

+ (void)load
{
    NSLog(@"Person---load");
}


+ (void)initialize
{
    NSLog(@"Person-initialize");
}

3.获取类对象的2种方式
Class c = [Person class]; // 类方法
或者
Person *p = [Person new];
Class c2 = [p class]; // 对象方法

4.类对象调用类方法
Class c = [Person class];
Person *p2 = [c new];

十、description方法
    NSLog(@"%@", p);
  默认情况下,利用NSLog和%@输出对象时,结果是:<类名:内存地址>
   
  1.会调用对象p的-description方法
  2.拿到-description方法的返回值(NSString *)显示到屏幕上
  3.-description方法默认返回的是“类名+内存地址”

    


1.-description方法
使用NSLog和%@输出某个对象时,会调用对象的-description方法,并拿到返回值进行输出
2.+ description方法
使用NSLog和%@输出某个类对象时,会调用类对象+description方法,并拿到返回值进行输出
3.修改NSLog的默认输出
>重写-description或者+description方法即可
 
决定了实例对象的输出结果
- (NSString *)description
{
  
     NSLog(@"%@", self);     // 代码会引发死循环
    return [NSString stringWithFormat:@"age=%d, name=%@", _age, _name];
   return @"3424324";
}

 决定了类对象的输出结果
+ (NSString *)description
{
    return @"Abc";
}


4.死循环陷阱
>如果在-description方法中使用NSLog打印self


十一、SEL
 1.SEL其实是对方法的一种包装,将方法包装成一个SEL类型的数据,去找对应的方法地址。找到方法地址就可以调用方法
其实消息就是SEL.
>每个类的方法列表都存储在类对象中
>每个方法都有一个与之对应的SEL类型的对象
>根据一个SEL对象就可以找到方法的地址,进而调用方法

2.SEL对象的创建
SEL s = @selector(test);
SEL s2 = NSSelectorFromString(@"test");

3.SEL对象的其他用法
// 将SEL对象转为NSString对象
NSString *str = NSStringFromSelector(@selector(test));

Person *p = [Person new];
// 调用对象p的test方法
[p performSelector:@selector(test)];


代码示例:
//Person.m实现文件
+ (void)test
{
    NSLog(@"test-----");
}

- (void)test2
{
    // _cmd代表着当前方法
   
    NSString *str = NSStringFromSelector(_cmd);
   
    // 会引发死循环
    // [self performSelector:_cmd];
   
    NSLog(@"调用了test2方法-----%@", str);
}

- (void)test3:(NSString *)abc
{
    NSLog(@"test3-----%@", abc);
}


//main函数
Person *p = [[Person alloc] init];
   
    [p test2];
   
//    NSString *name = @"test2";
//   
//    SEL s = NSSelectorFromString(name);
//   
//    [p performSelector:s];
   
   
    // 间接调用test2方法
    //[p performSelector:@selector(test2)];
   
    //[p test3:@"123"];
   
   
//    SEL s = @selector(test3:);
//   
//    [p performSelector:s withObject:@"456"];
   
    //[p test2];


   
  1.把test2包装成SEL类型的数据
   2.根据SEL数据找到对应的方法地址
   3.根据方法地址调用对应的方法

十二、NSLog输出增强
__FILE__ :源代码文件名
__LINE__ :NSLog代码在第几行
_cmd :代表着当前方法的SEL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值