Right way to use __attribute__((NSObject)) with AR

2019-09-10 03:07发布

I just use CFNumber as a example,so it can be any type don't have a Fundation toll-free part!

I just write some test code like this:

typedef  __attribute__((NSObject)) CFNumberRef MYNumberRef;

int main(int argc, const char * argv[])
{

    @autoreleasepool {
    MYNumberRef ptr = NULL;
    double myDouble = 10.1;
    ptr = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &myDouble);
    CFIndex count = CFGetRetainCount(ptr);
    }
    return 0;
}

It is very strange that the count is 2. But if I use CFNumberRef, the count is 1. It seems the arc don't take the CFType name convention into account, it just retains the return value.

So if I use the __attribute__((NSObject)) to declare CFType property. This post said you shouldn't have to explicitly nil them out in dealloc. But if I use like this:

   @property (strong, nonatomic, readwrite) __attribute__((NSObject)) CFNumberRef number;

Then:

   self.number = CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &myDouble);

There is no memory leak if I don't release it in the dealloc method? Maybe I should use it like this:

  CFNumbeRef ref =  CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &myDouble);
  self.number = ref;
  CFRelease(ref);

Does Apple say something about this?

1条回答
爱情/是我丢掉的垃圾
2楼-- · 2019-09-10 03:54

Do not do this.

Apple does have something to say about it in the Clang documentation:

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.

CFGetRetainCount is meaningless. Worse than meaningless because you think it might mean something.

查看更多
登录 后发表回答