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

倾然丶 夕夏残阳落幕 提交于 2019-12-02 16:43:37

-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).

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!