objc_release_properties.mm 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. // Copyright 2016 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/mac/objc_release_properties.h"
  5. #include <memory>
  6. #include <objc/runtime.h>
  7. #include "base/check.h"
  8. #include "base/memory/free_deleter.h"
  9. namespace {
  10. bool IsRetained(objc_property_t property) {
  11. // The format of the string returned by property_getAttributes is documented
  12. // at
  13. // http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6
  14. const char* attribute = property_getAttributes(property);
  15. while (attribute[0]) {
  16. switch (attribute[0]) {
  17. case 'C': // copy
  18. case '&': // retain
  19. return true;
  20. }
  21. do {
  22. attribute++;
  23. } while (attribute[0] && attribute[-1] != ',');
  24. }
  25. return false;
  26. }
  27. id ValueOf(id obj, objc_property_t property) {
  28. std::unique_ptr<char, base::FreeDeleter> ivar_name(
  29. property_copyAttributeValue(property, "V")); // instance variable name
  30. if (!ivar_name)
  31. return nil;
  32. id ivar_value = nil;
  33. Ivar ivar = object_getInstanceVariable(obj, &*ivar_name,
  34. reinterpret_cast<void**>(&ivar_value));
  35. DCHECK(ivar);
  36. return ivar_value;
  37. }
  38. } // namespace
  39. namespace base::mac::details {
  40. void ReleaseProperties(id self, Class cls) {
  41. unsigned int property_count;
  42. std::unique_ptr<objc_property_t[], base::FreeDeleter> properties(
  43. class_copyPropertyList(cls, &property_count));
  44. for (size_t i = 0; i < property_count; ++i) {
  45. objc_property_t property = properties[i];
  46. if (!IsRetained(property))
  47. continue;
  48. [ValueOf(self, property) release];
  49. }
  50. }
  51. } // namespace base::mac::details