OC 最重要的语法

来源:互联网 发布:淘宝死人衣服图片 编辑:程序博客网 时间:2024/06/06 13:58
最重要的语法


点语法: 
  点语法的本质还是方法调用(即指向方法)
 
  Person *p = [Person new];  -  (void)setAge:(int)age  {         _age=age;  }  - (int)age  {         return _age;  }  

    不写成员变量,但是写@property的话,那么在@implementation中使用@synthesize的话,访问成员变量,如果不存在的话,就会自动生成@private的成员变量,数据类型根据@property中的数据类型。(这个变量是生成在@implementation中的)
 
    写法:直接写一个@property int age;
                这句话将会完成的任务:
                    1、生成age的get和set方法声明
                    2、生成一个int类型的成员变量  int _age;(因为生成的变量是@private,所以如果子类需要访问的话,还是需要我们自己写成员变量,这样就不会生成私有的成员变量了)
                    3、生成age的get和set方法的实现
 
    @synthesize实现
       @synthesize age=_age
        1、setter和getter实现中会访问成员变量_age;
        2、如果成员变量不存在,就会自动生成一个@private的成员变量_age
       @synthesize age
          1、setter和getter实现中会访问age变量
          2、如果成员变量age不存在,就会自动生成一个@private的成员变量age
       手动实现
          1、若手动实现setter方法,编译器就只会自动生成getter方法
          2、若手动实现getter方法,编译器就只会自动生成setter方法
          3、若手动同时实现了setter和getter方法,编译器就不会自动生成不存在的成员变量
        
关键字:id         
    id是万能指针,能指向\操作任何OC对象
    id内部包含*,所以声明变量的时候不需要带 *
    NSString * (字符串)也是OC对象,所以id也可以指向字符串
    也就是说 id 相当于  NSObject  *
 
    id类型的定义:      
   typedef  struct objc object{
             Class isa;
         } *id;
    局限性:
        调用一个不存在的方法的时候,编译器会马上报错
 
 
构造方法:对象方法
    构造方法:用来初始化对象的方法,是个对象方法,以 -号开头
    重写构造方法的目的:为了让对象创建出来,成员变量就会有一些固定的值
    
    Person *p = [Person new];
    new方法完整的创建一个对象(分别调用两个方法完成下面的工作):
        1、分配存储空间(+alloc)
        2、初始化(-init)
    
    new方法内部进行的工作:
   
  //调用+alloc方法分配存储空间     Person *p1 = [Person alloc];     //调用-init方法进行初始化     Person *p2 = [p1  init]; 

 
    init方法就是构造方法:
    等价于:Person *p = [[Person alloc] init];
 
    对象初始化之后,对象的成员变量默认为0
 
    当要求每个Person对象创建出来的时候,他的成员变量_age都是10
        构造方法的注意点:
        1、先调用父类的构造方法 ([super init])
        2、在进行子类内部成员变量的初始化
        //重写-init方法


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


自定义构造函数:    
    自定义构造函数分两步:
        第一步:声明
        第二步:实现
        
    自定义构造方法的规范:
        1、一定是对象方法,一定以   -   开头
        2、返回值一般是id类型
        3、方法名一般以initWith开头
    声明:
     - (id)initWithName:(NSString *)name;
 
    实现:     


        - (id)initWithName:(NSString *)name         {             if(self = [super init])             {                 _name=name;             }             return self;         }

 


      当子类中的初始化方法需要使用父类的成员变量的时候,原则是:子类中的成员变量在子类中初始化,父类的成员变量在父类中初始化。(父类中提供初始化方法,然后子类将值传递过来)
      这样做的好处就是:当父类中的成员变量发生变化的时候,子类不需要更改不会报错。直接改父类就行了
        
 
Category:分类
    分类:可以给某一个类扩充一些方法(个人理解是修改给已经存在的类添加一些方法)
    
    //声明    @interface 类名 (分类名称)     @end        //实现    @implementaion 类名 (分类名称)     @end


 
    使用注意:
        1、分类只能增加方法,不能增加成员变量
        2、分类方法实现中可以访问原来类中声明的成员变量
        3、如果分类中的方法与原来类中的方法重名,那么优先调用的是分类中的方法。(这样就会覆盖原来类中的方法,原来类中的方法将不能使用)
        4、方法调用的优先级:分类(最后参与编译的分类优先)-->原来类-->父类
 
 characterAtIndex:<#(NSUInteger)#>:字符串的这个方法是获取指定位置上的字符(位置序号从0开始)
 
 
类的本质:
    1、类也是个对象。简称“类对象”
        其实类也是一个对象,是一个Class类型的对象。
            Class关键字内部包含 * ,使用的时候后面不需要加 *
        利用Person类对象,创建Person类型的对象
        
        //获取内存中的类对象(获取到的类对象可以调用类方法)
        Person *p = [[Person alloc] init];
        Class c = [p class];
        或者:Class  c = [Person class];
    
    2、类的加载过程:
        + (void)load:方法,在类被加载的时候调用
        程序启动的时候会加载所有的类和分类,并调用所有类和分类的+load方法。
        先加载父类,再加载子类,也就是先调用父类的+load,再调用子类的+load。
        先加载原始类,再加载分类。
        不管程序运行过程中有没有用到这个类,都会调用+load加载。
 
        +initialize
        在第一次使用某个类时(比如创建对象等),就会调用一次+initialize方法。
        一个类只会调用一次+initialize方法,先调用父类的,在调用子类的。        
    
description方法:
    -description(决定实例对象的输出结果)
 
    Person *p = [[Person alloc] init];
    //默认情况下,利用NSLog和%@输出对象时,结果是: <类名:内存地址>
    NSLog(@"%@",p);
    打印OC对象使用的占位符是%@
    打印OC对象的话(除了NSString *),显示的是类名加上类在内存中的地址
    
    执行NSLog(@"%@",p);这句代码的时候:
        1、首先会调用对象p的-description方法
        2、拿到-description方法的返回值(NSString *)显示到屏幕上
        3、-description方法默认返回的是“类名:内存地址”
    当想输出对象的内容的时候,可以在类的实现中重写-description方法:
  
  - (NSString *)description {     return [NSString stringWithFormat:@"age=%d,name=%@",_age,_name]; }    //不要在description中尝试输出self:NSLog(@"%@",self),这样会引发死循环     // +description(决定类对象的输出结果)        Class c = [Person class];     //会调用类的+description方法    //拿到+description方法的返回值(NSString *)显示到屏幕上(默认返回的是类名)    NSLog(@"%@",c);    

NSLog():   
    打印指针中存储的对象的内存地址:
        NSLog(@"%p",p);
    打印指针变量自己的内存地址:
        NSLog(@"%p", &p);
 
    NSLog()输出C语言字符串的时候,不能有中文
        NSLog(@"%s",_func_);//输出当前方法名称
        NSLog(@"%d",_LINE_);//输出当前行号
        NSLog(@"%s",_FILE_);//输出当前源文件的完整路径
        NSLog(@"%s",__PRETTY_FUNCTION__ );//返回当前方法或函数的完整的函数名(包括返回值和参数)
    
 
SEL类型:
    一个类中都有SEL类型数据,一个SEL数据对应一个方法的地址
    Person *p = [[Person alloc] init];
    [p test2];
    
    1、把test2包装成SEL类型的数据
    2、根据SEL数据找到对应的方法地址
    3、根据方法地址调用对应的方法(这里使用的缓存技术,第一次会查找,以后就会使用第一次查找的结果)
 
    间接调用test2方法
        [p performSelector:@selector(test2)];
    
   方法的存储位置:
        每个类的方法列表都存储在类对象中
        每个方法都有一个与之对应的SEL类型的数据
        根据一个SEL对象就可以找到方法的地址,进而调用
        SEL类型的定义
        typedef struct objc_selector   *SEL;
 
    SEL对象的创建
        SEL s=@selector(test);
        SEL s2=NSSelectorFormString(@"test");
 
    NSSelectorFormString(@"test");//将一个字符串类型的数据传进去转换成SEL数据




总的来说,OC语言是比较灵活的一门语言。
0 0
原创粉丝点击