association.m 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // TEST_CONFIG
  2. #include "test.h"
  3. #include <Foundation/NSObject.h>
  4. #include <objc/runtime.h>
  5. static int values;
  6. static int supers;
  7. static int subs;
  8. static const char *key = "key";
  9. @interface Value : NSObject @end
  10. @interface Super : NSObject @end
  11. @interface Sub : NSObject @end
  12. @interface Super2 : NSObject @end
  13. @interface Sub2 : NSObject @end
  14. @implementation Super
  15. -(id) init
  16. {
  17. // rdar://8270243 don't lose associations after isa swizzling
  18. id value = [Value new];
  19. objc_setAssociatedObject(self, &key, value, OBJC_ASSOCIATION_RETAIN);
  20. RELEASE_VAR(value);
  21. object_setClass(self, [Sub class]);
  22. return self;
  23. }
  24. -(void) dealloc
  25. {
  26. supers++;
  27. SUPER_DEALLOC();
  28. }
  29. @end
  30. @implementation Sub
  31. -(void) dealloc
  32. {
  33. subs++;
  34. SUPER_DEALLOC();
  35. }
  36. @end
  37. @implementation Super2
  38. -(id) init
  39. {
  40. // rdar://9617109 don't lose associations after isa swizzling
  41. id value = [Value new];
  42. object_setClass(self, [Sub2 class]);
  43. objc_setAssociatedObject(self, &key, value, OBJC_ASSOCIATION_RETAIN);
  44. RELEASE_VAR(value);
  45. object_setClass(self, [Super2 class]);
  46. return self;
  47. }
  48. -(void) dealloc
  49. {
  50. supers++;
  51. SUPER_DEALLOC();
  52. }
  53. @end
  54. @implementation Sub2
  55. -(void) dealloc
  56. {
  57. subs++;
  58. SUPER_DEALLOC();
  59. }
  60. @end
  61. @implementation Value
  62. -(void) dealloc {
  63. values++;
  64. SUPER_DEALLOC();
  65. }
  66. @end
  67. int main()
  68. {
  69. testonthread(^{
  70. int i;
  71. for (i = 0; i < 100; i++) {
  72. RELEASE_VALUE([[Super alloc] init]);
  73. }
  74. });
  75. testcollect();
  76. testassert(supers == 0);
  77. testassert(subs > 0);
  78. testassert(subs == values);
  79. supers = 0;
  80. subs = 0;
  81. values = 0;
  82. testonthread(^{
  83. int i;
  84. for (i = 0; i < 100; i++) {
  85. RELEASE_VALUE([[Super2 alloc] init]);
  86. }
  87. });
  88. testcollect();
  89. testassert(supers > 0);
  90. testassert(subs == 0);
  91. testassert(supers == values);
  92. // rdar://44094390 tolerate nil object and nil value
  93. #pragma clang diagnostic push
  94. #pragma clang diagnostic ignored "-Wnonnull"
  95. objc_setAssociatedObject(nil, &key, nil, OBJC_ASSOCIATION_ASSIGN);
  96. #pragma clang diagnostic pop
  97. succeed(__FILE__);
  98. }