Workaround Objective-C 2.0 properties bug
authorWincent Colaiuta <win@wincent.com>
Sat, 11 Aug 2007 11:42:17 +0000 (13:42 +0200)
committerWincent Colaiuta <win@wincent.com>
Sat, 11 Aug 2007 11:43:49 +0000 (13:43 +0200)
It turns out that the public-readonly/private-readwrite property pattern is
not broken after all, and a simple workaround is available (redeclare all the
attributes "in whole" rather than "in part" as the documentation suggests).

This commit applies the new workaround and references the Radar and test case
that correspond to the issue.

Signed-off-by: Wincent Colaiuta <win@wincent.com>
Signed-off-by: Wincent Colaiuta <win@wincent.com>
WOTestClass.h
WOTestClass.m

index ef7820d5be6d01414cb344c50783c9020441a766..59721f95ff243609c30f47f9d3254a75e2db6a41 100644 (file)
 //! \name Properties
 //! \startgroup
 
-// BUG: Objective-C 2.0 bug, can't use "readonly" pattern, see implementation file for more details
-@property(/*readonly,*/ copy) NSDate    *startDate;
-@property/*(readonly)*/ unsigned        testsRun;
-@property/*(readonly)*/ unsigned        testsPassed;
-@property/*(readonly)*/ unsigned        testsFailed;
+@property(readonly, copy) NSDate    *startDate;
+@property(readonly) unsigned        testsRun;
+@property(readonly) unsigned        testsPassed;
+@property(readonly) unsigned        testsFailed;
 
 // TODO: need sense inversion here as well (for uncaught exceptions) for self-testing purposes
-@property/*(readonly)*/ unsigned        uncaughtExceptions;
-@property/*(readonly)*/ unsigned        testsFailedExpected;
-@property/*(readonly)*/ unsigned        testsPassedUnexpected;
+@property(readonly) unsigned        uncaughtExceptions;
+@property(readonly) unsigned        testsFailedExpected;
+@property(readonly) unsigned        testsPassedUnexpected;
 
 @property BOOL                      expectFailures;
 
-@property/*(readonly)*/ unsigned        lowLevelExceptionsExpected;
-@property/*(readonly)*/ unsigned        lowLevelExceptionsUnexpected;
+@property(readonly) unsigned        lowLevelExceptionsExpected;
+@property(readonly) unsigned        lowLevelExceptionsUnexpected;
 
 @property BOOL                      expectLowLevelExceptions;
 
 @property unsigned                  verbosity;
 @property unsigned                  trimInitialPathComponents;
-@property(/*readonly,*/ copy) NSString  *lastReportedFile;
-@property/*(readonly)*/ int             lastReportedLine;
+@property(readonly, copy) NSString  *lastReportedFile;
+@property(readonly) int             lastReportedLine;
 @property BOOL                      warnsAboutSignComparisons;
 
 //! \endgroup
index 690ca56ffdb9f81893a3688cbff55ba81be783d0..8f21e2e35847c2c83549eac663e1c0cc4e85498d 100644 (file)
@@ -171,31 +171,22 @@ OSStatus WOLowLevelExceptionHandler(ExceptionInformation *theException)
 //! Public properties previously declared readonly have a private readwrite implementation internally to the class.
 //! \startgroup
 
-// BUG: Objective-C 2.0 bug; the documentation would suggest that redeclaring all the attributes is not necessary
-//      "You can re-declare properties in a subclass, and you can repeat properties' attributes in whole or in part"
-//      "The same holds true for properties declared in a category"
-//      "the property's attributes must only be repeated in whole or part"
-// but warns:
-//      no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed
-// furthermore, it appears that the readwrite override does not actually cause a setter to be synthesized further down
-// despite what the docs say:
-//      "In the case of a category redeclaration, that the property was redeclared prior any @synthesize statement will cause the setter to be synthesized"
-// we get unrecognized selector exceptions:
-//      *** -[WOTest setTestsFailedExpected:]: unrecognized selector sent to instance 0x102eee0)
-// so for now must abandon the pattern
-//@property(readwrite, assign) NSDate     *startDate;
-//@property(readwrite) unsigned           testsRun;
-//@property(readwrite) unsigned           testsPassed;
-//@property(readwrite) unsigned           testsFailed;
-//@property(readwrite) unsigned           uncaughtExceptions;
-//@property(readwrite) unsigned           testsFailedExpected;
-//@property(readwrite) unsigned           testsPassedUnexpected;
-//@property(readwrite) unsigned           lowLevelExceptionsExpected;
-//@property(readwrite) unsigned           lowLevelExceptionsUnexpected;
-
-// BUG: as above (shouldn't have to explicitly re-declare "assign" here)
-//@property(readwrite, assign) NSString   *lastReportedFile;
-//@property(readwrite) int                lastReportedLine;
+// NOTE: The documentation would suggest that the repetition of the "copy" attribute here is not required, but without it the
+// compiler issues various warnings. A Radar has been filed against this (<rdar://problem/5403996>) as it appears to be either a
+// compiler bug or a documentation bug. The corresponding test case can be found in the other/readonly_readwrite_properties_bug
+// subdirectory.
+
+@property(readwrite, copy) NSDate   *startDate;
+@property(readwrite) unsigned       testsRun;
+@property(readwrite) unsigned       testsPassed;
+@property(readwrite) unsigned       testsFailed;
+@property(readwrite) unsigned       uncaughtExceptions;
+@property(readwrite) unsigned       testsFailedExpected;
+@property(readwrite) unsigned       testsPassedUnexpected;
+@property(readwrite) unsigned       lowLevelExceptionsExpected;
+@property(readwrite) unsigned       lowLevelExceptionsUnexpected;
+@property(readwrite, copy) NSString *lastReportedFile;
+@property(readwrite) int            lastReportedLine;
 
 //! \endgroup