accessors.m 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. // TEST_CFLAGS -framework Foundation
  2. #import <Foundation/Foundation.h>
  3. #import <objc/runtime.h>
  4. #import <objc/objc-abi.h>
  5. #include "test.h"
  6. @interface Test : NSObject {
  7. NSString *_value;
  8. // _object is at the last optimized property offset
  9. id _object __attribute__((aligned(64)));
  10. }
  11. @property(readonly) Class cls;
  12. @property(copy) NSString *value;
  13. @property(assign) id object;
  14. @end
  15. typedef struct {
  16. void *isa;
  17. void *_value;
  18. // _object is at the last optimized property offset
  19. void *_object __attribute__((aligned(64)));
  20. } TestDefs;
  21. @implementation Test
  22. // Question: why can't this code be automatically generated?
  23. #if !__has_feature(objc_arc)
  24. - (void)dealloc {
  25. self.value = nil;
  26. self.object = nil;
  27. [super dealloc];
  28. }
  29. #endif
  30. - (Class)cls { return objc_getProperty(self, _cmd, 0, YES); }
  31. - (NSString*)value { return (NSString*) objc_getProperty(self, _cmd, offsetof(TestDefs, _value), YES); }
  32. - (void)setValue:(NSString*)inValue { objc_setProperty(self, _cmd, offsetof(TestDefs, _value), inValue, YES, YES); }
  33. - (id)object { return objc_getProperty(self, _cmd, offsetof(TestDefs, _object), YES); }
  34. - (void)setObject:(id)inObject { objc_setProperty(self, _cmd, offsetof(TestDefs, _object), inObject, YES, NO); }
  35. - (NSString *)description {
  36. return [NSString stringWithFormat:@"value = %@, object = %@", self.value, self.object];
  37. }
  38. @end
  39. int main() {
  40. PUSH_POOL {
  41. NSMutableString *value = [NSMutableString stringWithUTF8String:"test"];
  42. id object = [NSNumber numberWithInt:11];
  43. Test *t = AUTORELEASE([Test new]);
  44. t.value = value;
  45. [value setString:@"yuck"]; // mutate the string.
  46. testassert(t.value != value); // must copy, since it was mutable.
  47. testassert([t.value isEqualToString:@"test"]);
  48. Class testClass = [Test class];
  49. Class cls = t.cls;
  50. testassert(testClass == cls);
  51. cls = t.cls;
  52. testassert(testClass == cls);
  53. t.object = object;
  54. t.object = object;
  55. // NSLog(@"t.object = %@, t.value = %@", t.object, t.value);
  56. // NSLog(@"t.object = %@, t.value = %@", t.object, t.value); // second call will optimized getters.
  57. } POP_POOL;
  58. succeed(__FILE__);
  59. return 0;
  60. }