Objective-C中添加一个CFStringRef对象的属性

MRC文件: RXMRCUtil.m

+ (NSUInteger)objectRetainCount:(id)object
{
    return [object retainCount];
}

测试

@interface RXARCAttributeNSObjectObject()
// 需要自己的内存管理
//@property (nonatomic, assign) CFStringRef stringRef;
// COMPILE ERROR:Property with 'retain (or strong)' attribute must be of object type
//@property (nonatomic, strong) CFStringRef stringRef;
@property (nonatomic, strong) __attribute__((NSObject)) CFStringRef stringRef;
@end
@implementation RXARCAttributeNSObjectObject

- (void)test
{
    // 字符串一定要这种奇怪的"123-%d-abc",不能用简单的"123", "abc",要不然引用计数不准确
    CFStringRef stringRef = CFStringCreateWithCString(CFAllocatorGetDefault(), "123-%d-abc", kCFStringEncodingUTF8);
    NSString *string = (__bridge NSString *)stringRef;
    NSLog(@"after create and bridge cast count1:%zd", [RXMRCUtil objectRetainCount:string]);
    self.stringRef = stringRef;
    NSLog(@"after self.stringRef count2:%zd", [RXMRCUtil objectRetainCount:string]);
    self.stringRef = nil;
    NSLog(@"after self.stringRef = nil count3:%zd", [RXMRCUtil objectRetainCount:string]);
    CFRelease(stringRef);
    NSLog(@"after CFRelease count4:%zd", [RXMRCUtil objectRetainCount:string]);
}
@end

示例代码中有相关的注释,输出结果:

after create and bridge cast count1:2
after self.stringRef count2:3
after self.stringRef = nil count3:2
after CFRelease count4:1

count1 = 2的原因是,create产生1个,__bridge产生1个(这个可以参考ARC下 bridged cast探究)。
后面的就好理解了。所以一个属性是CF对象的时候,需要使用上述的方法。

AFNetworkReachabilityManager中有如下的相关代码:

@property (readonly, nonatomic, assign) SCNetworkReachabilityRef networkReachability;


_networkReachability = CFRetain(reachability);

- (void)dealloc {
    [self stopMonitoring];
    
    if (_networkReachability != NULL) {
        CFRelease(_networkReachability);
    }
}

如果使用了 __attribute__((NSObject)) 估计就不用写那么多的代码了。

但是:

The use of __attribute__((NSObject)) typedefs is not recommended. If it’s absolutely necessary to use this attribute, be very explicit about using the typedef, and do not assume that it will be preserved by language features like __typeof and C++ template argument substitution.

Any compiler operation which incidentally strips type “sugar” from a type will yield a type without the attribute, which may result in unexpected behavior.

在ARC文档中,貌似是不推荐这种用法。

猜你喜欢

转载自blog.csdn.net/weixin_34192732/article/details/87492792