OC 最重要的语法

最重要的语法


点语法: 
  点语法的本质还是方法调用(即指向方法)
 
  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语言是比较灵活的一门语言。
「LLM那些事」系列第 4 篇《上下文窗口的边界》,文章连接:https://blog.csdn.net/houwenjin/article/details/163999753。 演示什么:在「预测」Sheet 的黄色格子里输入一句话(默认「来泡一杯」),四个「模型」——分别只统计最后 1 / 2 / 3 / 4 个字的 n-gram 查表——同时预测下一个字。同一个输入,看的上下文越长,候选越少、预测越确定: ┌────────────────┬──────────┬───────────────┬──────┐ │ 只看最后几个字 │ 用的前缀 │ 候选下一字数 │ 预测 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 1 个 │ 杯 │ 3(茶/子/水) │ 模糊 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 2 个 │ 一杯 │ 2(茶/水) │ 收窄 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 3 个 │ 泡一杯 │ 1(茶) │ 确定 │ ├────────────────┼──────────┼───────────────┼──────┤ │ 4 个 │ 来泡一杯 │ 1(茶) │ 确定 │ └────────────────┴──────────┴───────────────┴──────┘
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值