0

Edit 2: In addition to Kurt's solution, there is one more way to do it. Take a look at the end of this page, just before comments: http://www.friday.com/bbum/2009/09/11/class-extensions-explained/


Edit: It seems class methods in a class category cannot access private members such as ivars and private methods that are implemented through class extensions.


I hope this question is not asked and answered before, but I could not find one as both stackoverflow and Google search spams my browser window with kinds of questions that ask to access an ivar directly from a class method, which is clearly not my intention.

Straight to the problem, I'll provide a piece of code, which summarizes what I'm trying to accomplish:


XYZPerson.h:

@interface XYZPerson : NSObject
@property (weak, readonly) XYZPerson *spouse;
@end

XYZPersonMariage.h:

@interface XYZPerson (XYZPersonMariage)
+(BOOL)divorce:(XYZPerson *) oneOfSpouses;
@end

XYZPersonMariage.m

+(BOOL)divorce:(XYZPerson *)oneOfSpouses
{
  XYZPerson *otherSpouse = [oneOfSpouses spouse];
  if(otherSpouse != nil)
  {
    oneOfSpouses->_spouse = nil;
    otherSpouse->_spouse = nil;
    return true;
  }
  return false;
}

I first thought that maybe an ivar is not automatically synthesized for a property flagged readonly, but it is indeed synthesized.

So, what paths can I take to get the job done?

4

1 回答 1

2

Your method +[XYZPerson divorce:] is defined in XYZPersonMarriage.m, which is a different compilation unit than XYZPerson.m where the rest of XYZPerson is implemented.

Because of this, when compiling +divorce:, the compiler doesn't know there's an implicitly synthesized _spouse variable. For all it knows, the property could be backed by a method -spouse that you implemented.

Ways to get around this:

  • Move the implementation of +divorce into XYZPerson.m.

  • Don't access ivars directly, but do the work via real methods. They don't have to be part of the usual public interface of the class; they can be exposed via a separate header file that only XYZPersonMarriage.m imports. Search for "Objective-C private method" for more discussion on the pros and cons of that pattern.

于 2013-02-05T17:46:55.113 回答