美文网首页
Objective-C 碎碎念 3

Objective-C 碎碎念 3

作者: 大地瓜123 | 来源:发表于2017-08-23 13:39 被阅读0次

    本文为大地瓜原创,欢迎知识共享,转载请注明出处。
    虽然你不注明出处我也没什么精力和你计较。
    作者微信号:christgreenlaw


    如果只有方法的实现而没有声明,那么类外部无法直接调用此方法。该方法就成为了表面上的私有方法。但是,OC中没有真正的私有方法,因为OC采用的是消息机制

    {}形式的实例变量(成员变量)可以在@interface中定义,也可以在@implementation中定义。而在@implementation中定义的变量和用@private修饰的变量又不太一样,在@implementation中定义的变量只能在本类中访问,其它类无法查看


    @property是一个编译器指令。
    @synthesize是一个编译器指令, 它可以简化我们getter/setter方法的实现。

    在@synthesize后面告诉编译器,将要使用的property叫什么,对应的实例变量叫什么。例子如下:

    - (void)setAge:(int)age
    {
       _age = age;
    }
    - (int)age
    {
       return _age;
    }
    
    //@synthesize age = _age;
    
     - (void)setAge:(int)age
     {
        _number = age;
     }
     - (int)age
     {
        return _number;
     }
     
    //@synthesize age = _number;
    

    如果在@synthesize后面没有告诉系统将传入的值赋值给谁, 系统默认会赋值给和@synthesize后面写得名称相同的成员变量(Xcode4.4之前这个才有意义,目前的@property实现默认就是这样)

    @synthesize age;
    
    - (void)setAge:(int)age
    {
        _age = age;
    }
    
    - (int)age
    {
        return _age;
    }
    

    在目前的实现中,当@property声明了一个变量,默认就会使用对应的下划线开头的实例变量(这个实例变量就不必用花括号的形式写出了)。但需要注意的是:它只会生成最简单的getter/setter,不会对其进行其他操作。若需要对数据进行处理,则需要我们自己重写getter/setter。

    注意!!!!如果你同时重写了getter和setter,那么@property将不会为你生成下划线开头的实例变量!!!你需要手动在花括号中声明实例变量!!!


    property修饰符

    @property(readwrite) int age;
    @property(getter=myName) NSString* name;
    @property(setter=giveName:) NSString* name;
    @property(getter=myName,setter=giveName:) NSString* name;
    @property(readonly) NSString* id;
    @property(getter=isMarried) NSString* married;
    //能用修饰符处理的getter/setter就尽量不要额外去写了,统一用修饰符处理


    id

    id是一个动态数据类型,可以用来:

    1. 定义变量
    2. 作为函数参数类型
    3. 作为函数返回值类型

    一般情况下,所有的数据类型都是静态数据类型,也就是说:

    • 编译时就知道是什么类型
    • 知道类型有哪些方法和属性
    • 编译时就可以确定的访问类型的方法和属性
    • 若通过静态类型定义变量,那么访问不属于静态类型的方法或属性,编译器会报错,无法通过编译

    作为动态类型:

    • 编译时不知道真是的类型,运行时才知道它的真实类型
    • 通过动态数据类型定义变量,如果访问不属于动态数据类型的方法或属性,编译时不会报错

    一句话总结:动态数据类型,编译器不知道你的真实类型,静态类型反之

    • 通过静态数据类型定义变量, 不能调用子类特有的方法
    • 通过动态数据类型定义变量, 可以调用子类特有的方法
    • 通过动态数据类型定义的变量, 可以调用私有方法

    为了避免动态数据类型调用不属于自己的方法而引发的运行时错误,一般在使用前进行判断,是不是能够调用某方法:

    if ([obj isKindOfClass:[Student class]]) {
      // isKindOfClass , 判断指定的对象是否是某一个类, 或者是某一个类的子类
      [obj eat];
    }
        
       
    if ([obj isMemberOfClass:[Student class]]) {
      // isMemberOfClass : 判断指定的对象是否是当前指定的类的实例
      [obj eat];
    }
    

    new方法其实就是alloc + init
    默认情况下init(NSObject)什么都没有做
    alloc则初始化了isa实例变量,使其指向了自己所在的类,其他所有实例变量的值都设为0
    由于历史原因,alloc会触发allocWithZone:

    以上引用内容来自苹果文档。

    相关文章

      网友评论

          本文标题:Objective-C 碎碎念 3

          本文链接:https://www.haomeiwen.com/subject/zchddxtx.html