mostruash
mostruash

Reputation: 4189

Accessing ivar of an instance of the same class in a class method

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?

Upvotes: 0

Views: 468

Answers (1)

Kurt Revis
Kurt Revis

Reputation: 27984

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.

Upvotes: 2

Related Questions