Why does a (copy, nonatomic) NSMutableArray property create NSArrays?

后端 未结 2 1170
情书的邮戳
情书的邮戳 2021-01-31 04:52

I made a mistake while creating a TableView class, and accidentally kept my @property as copy when I defined it:

@property         


        
相关标签:
2条回答
  • 2021-01-31 05:07

    -copy, as implemented by mutable Cocoa classes, always returns their immutable counterparts. Thus, when an NSMutableArray is sent -copy, it returns an NSArray containing the same objects.

    Because words has the memory qualifier copy, this line:

    NSMutableArray *mutWords = [[NSMutableArray alloc] initWithArray:fixedWords];
    self.words = mutWords;
    

    Expands out to:

    NSMutableArray *mutWords = [[NSMutableArray alloc] initWithArray:fixedWords];
    self.words = [mutWords copy];
    

    Given that NSMutableArray is a subclass of NSArray, the compiler doesn't complain, and you now have a ticking time bomb on your hands because NSArray does not recognize it's mutable subclass' methods (because it cannot mutate it's contents).

    0 讨论(0)
  • 2021-01-31 05:07

    Properties aren't magical, they're just shorthand. Declaring a @property on your object tells the compiler to create a backing instance variable and accessor methods for it. The actual generated code depends on the attributes you set on your property.

    It's important to remember that setting a property using dot syntax is also shorthand. When you call…

    self.words = mutWords;
    

    …you're actually invoking the generated accessor method behind the scenes, like this:

    [self setWords:mutWords];
    

    Since you specified the copy attribute on your property, you've told the compiler to generate that -setWords: accessor method with code that looks something like this:

    - (void)setWords:(NSMutableArray *)words
    {
        _words = [words copy];
    }
    

    Knowing all that, you can see what's happening: the generated setter method will call -copy on the input argument, and assign the result to the backing instance variable. Because the -copy method is always implemented to return a non-mutable object (performing [aMutableString copy] will return an NSString, and so on) setting that property will always store a non-mutable copy.

    0 讨论(0)
提交回复
热议问题