1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162 |
- // Copyright 2016 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "base/mac/objc_release_properties.h"
- #include <memory>
- #include <objc/runtime.h>
- #include "base/check.h"
- #include "base/memory/free_deleter.h"
- namespace {
- bool IsRetained(objc_property_t property) {
- // The format of the string returned by property_getAttributes is documented
- // at
- // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6
- const char* attribute = property_getAttributes(property);
- while (attribute[0]) {
- switch (attribute[0]) {
- case 'C': // copy
- case '&': // retain
- return true;
- }
- do {
- attribute++;
- } while (attribute[0] && attribute[-1] != ',');
- }
- return false;
- }
- id ValueOf(id obj, objc_property_t property) {
- std::unique_ptr<char, base::FreeDeleter> ivar_name(
- property_copyAttributeValue(property, "V")); // instance variable name
- if (!ivar_name)
- return nil;
- id ivar_value = nil;
- Ivar ivar = object_getInstanceVariable(obj, &*ivar_name,
- reinterpret_cast<void**>(&ivar_value));
- DCHECK(ivar);
- return ivar_value;
- }
- } // namespace
- namespace base::mac::details {
- void ReleaseProperties(id self, Class cls) {
- unsigned int property_count;
- std::unique_ptr<objc_property_t[], base::FreeDeleter> properties(
- class_copyPropertyList(cls, &property_count));
- for (size_t i = 0; i < property_count; ++i) {
- objc_property_t property = properties[i];
- if (!IsRetained(property))
- continue;
- [ValueOf(self, property) release];
- }
- }
- } // namespace base::mac::details
|