iOS - 自定义引用计数(MRC)

自定义引用计数(Custom Reference Counting)是指类可以通过重写 retain/release 等方法来实现自己的引用计数管理机制。这通常用于特殊场景下的内存管理优化。

1. 判断是否使用自定义引用计数

objectivec 复制代码
inline bool 
objc_object::hasCustomRR() {
    // 检查类是否实现了自定义的引用计数方法
    return ISA()->hasCustomRR();
}

// 调用路径
id objc_object::retain() {
    if (fastpath(!ISA()->hasCustomRR())) {
        // 使用系统默认的引用计数机制
        return sidetable_retain();
    } else {
        // 使用类自定义的引用计数机制
        return ((id(*)(objc_object *, SEL))objc_msgSend)(this, @selector(retain));
    }
}

2. 自定义引用计数的实现示例

objectivec 复制代码
@interface CustomObject : NSObject

@property (nonatomic, assign) NSUInteger customRefCount;

@end

@implementation CustomObject

- (id)retain {
    @synchronized(self) {
        self.customRefCount++;
    }
    return self;
}

- (void)release {
    BOOL shouldDealloc = NO;
    @synchronized(self) {
        self.customRefCount--;
        if (self.customRefCount == 0) {
            shouldDealloc = YES;
        }
    }
    
    if (shouldDealloc) {
        [self dealloc];
    }
}

- (NSUInteger)retainCount {
    @synchronized(self) {
        return self.customRefCount;
    }
}

3. 使用场景

3.1 单例对象

objectivec 复制代码
@implementation MySingleton

+ (instancetype)sharedInstance {
    static MySingleton *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super allocWithZone:NULL] init];
    });
    return instance;
}

// 防止释放
- (id)retain {
    return self;
}

- (oneway void)release {
    // 不执行任何操作
}

- (id)autorelease {
    return self;
}

3.2 特殊内存管理

objectivec 复制代码
@implementation PooledObject

// 对象池中的对象
- (id)retain {
    // 不增加引用计数,而是返回到对象池
    [[ObjectPool sharedPool] markAsInUse:self];
    return self;
}

- (void)release {
    // 不真正释放,而是返回到对象池
    [[ObjectPool sharedPool] returnToPool:self];
}

4. 注意事项

4.1 线程安全

objectivec 复制代码
- (id)retain {
    @synchronized(self) {
        // 确保线程安全的引用计数操作
        _customRefCount++;
    }
    return self;
}

4.2 内存泄漏防护

objectivec 复制代码
- (void)release {
    BOOL shouldDealloc = NO;
    {
        @synchronized(self) {
            _customRefCount--;
            if (_customRefCount == 0) {
                shouldDealloc = YES;
            }
        }
    }
    
    // 在同步块外执行 dealloc
    if (shouldDealloc) {
        [self dealloc];
    }
}

5. 优缺点

优点:

  1. 可以实现特殊的内存管理策略
  2. 适合特定场景的优化
  3. 可以实现对象池等高级功能

缺点:

  1. 增加代码复杂度
  2. 可能引入bug
  3. 需要格外注意线程安全
  4. 可能影响系统的内存管理优化

6. 最佳实践

objectivec 复制代码
@implementation CustomRefCountObject

// 1. 清晰的文档
/**
 * 这个类使用自定义引用计数来实现对象池
 * 注意:不要直接创建实例,请使用 getFromPool 方法
 */

// 2. 完整的方法实现
- (id)retain {
    if (_customManaged) {
        return [self customRetain];
    }
    return [super retain];
}

// 3. 防御性编程
- (void)release {
    if (_customManaged) {
        [self customRelease];
        return;
    }
    [super release];
}

// 4. 调试支持
- (NSUInteger)retainCount {
    if (_customManaged) {
        return [self customRetainCount];
    }
    return [super retainCount];
}

自定义引用计数应该谨慎使用,只在确实需要的特殊场景下采用。大多数情况下,系统默认的引用计数机制就足够了。

相关推荐
恋猫de小郭27 分钟前
腾讯 Kuikly 正式开源,了解一下这个基于 Kotlin 的全平台框架
android·前端·ios
超人强2 小时前
一文搞定App启动流程、时间监测、优化措施
ios
一牛4 小时前
Appkit: 菜单是如何工作的
macos·ios·objective-c
tkevinjd5 小时前
文件操作、流对象示例
macos·objective-c·cocoa
JQShan7 小时前
React Native小课堂:箭头函数 vs 普通函数,为什么你的this总迷路?
javascript·react native·ios
画个大饼10 小时前
Swift与iOS内存管理机制深度剖析
开发语言·ios·swift
Ya-Jun16 小时前
常用第三方库:flutter_boost混合开发
android·flutter·ios
Dachui_11221 天前
MacOS上如何运行内网穿透详细教程
macos
玫瑰花开一片一片1 天前
Flutter IOS 真机 Widget 错误。Widget 安装后系统中没有
flutter·ios·widget·ios widget