Objective-C 碎碎念 3

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