iOS 中对象与内存的不完全记录

  • 类型系统

    1. 引用类型( refrence type)

      • 类( class )
      • 指针( pointer )
      • 块( block )
    2. 值类型( value type )

      • 基础数据类型( int, float, double... )
      • 机构体( struct )
      • 枚举( enum )
    3. 类型装饰

      • 协议( protocol )
      • 类别( category )
      • 扩展( extension )
  • 变量

    • 成员变量: @interface {} 中定义的变量

      • @public: 公开访问, 即使定义在 .m 文件中
      • @private: 私有访问, 默认
      • 使用 self->valueName 来访问
    • 属性: @property 定义的变量 or 对象

      • 修饰关键字

        • atmoic: 对 setter/getter 方法加锁(spinlock 自旋锁), 防止多个线程被同时访问(其他线程访问是会等待当前操作完成), 但有额外的资源开销, 且不保证数据的正确性
        • nonatmoic: 不加锁
        • setter/getter = methodName: 指定 setter/getter 的实现方法名
        • readwrite/readonly: 读写选项
        • dynamic: 由开发者实现 setter 和 getter, 声明之后无法使用 _name 的方式访问属性.
        • assign: 指针赋值, 引用计数不会增加, 一般用于基础数据类型和 c 数据类型. 不会自动置 nil. 即声明 A(assign), B=A, A 销毁后 B 的指针就变成了野指针.
        • weak: 声明为 weak 弱引用的对象, 赋值时不会引起赋值对象的引用计数变动, 且赋值对象销毁时, 自身会自动置 nil.
        • strong: 声明为 strong 强引用的对象, 赋值时会引起赋值对象的引用计数+1, 同时释放前一次持有的对象.
        • copy: 声明为 copy 的对象, 每次赋值时都会对赋值对象进行 copy 操作, 使用的是赋值对象的副本, 所以不引起赋值对象的引用计数变动. 注意生成的是不可变版本(非 Mutable)
  • 内存使用

    • 每个函数被调用时都会分配一个独立的栈内存空间
    • 栈(Stack): 由系统管理, 存储函数体的入参, 对象和属性参数地址
    • 堆(Heap): 由开发者管理, 或进程结束时系统全部回收, 存储引用类型, 属性参数的实际内容(值)
  • 析构器和初始化器

    • alloc: 在堆中按对象类型来申请分配合适的空间, 同时将属性和实例变量的内存地址置为 nil(或 0)
    • init: 调用父类 [super init], 并初始化对象的实例变量
    • dealloc: ARC 下对对象属性的引用计数 -1

设置 property 源码

static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 
{
   if (offset == 0) {
       object_setClass(self, newValue);
       return;
   }

   id oldValue;
   id *slot = (id*) ((char*)self + offset);

   if (copy) {
       newValue = [newValue copyWithZone:nil];
   } else if (mutableCopy) {
       newValue = [newValue mutableCopyWithZone:nil];
   } else {
       if (*slot == newValue) return;
       newValue = objc_retain(newValue);
   }

   if (!atomic) {
       oldValue = *slot;
       *slot = newValue;
   } else {
       spinlock_t& slotlock = PropertyLocks[slot];
       slotlock.lock();
       oldValue = *slot;
       *slot = newValue;        
       slotlock.unlock();
   }

   objc_release(oldValue);
}

void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL atomic, signed char shouldCopy) 
{
   bool copy = (shouldCopy && shouldCopy != MUTABLE_COPY);
   bool mutableCopy = (shouldCopy == MUTABLE_COPY);
   reallySetProperty(self, _cmd, newValue, offset, atomic, copy, mutableCopy);
}

你可能感兴趣的:(ios,objective-c)