Are Mutable classes more heavy?

For some intuitive (possibly wrong) performance idea, I always get a copy mutable instance before I save it. Therefore, if the property expects an NSArray , I take the variable array that I am working with and save it as self.array = mutableArray.copy (although the property is indicated as strong or retain ).

It seems silly to me, all of a sudden, but does it? Sane instances β€” performing the same task β€” do the same thing?

Note. A volatile instance goes out of scope and (thanks to ARC) is freed immediately after that, so don't worry that it will mutate as soon as it is assigned to this property. p>

+4
source share
3 answers

NSArray and NSMutableArray both (as far as I know) implemented on top of CFArray , which simply has a flag that determines whether it is mutable. CFArray functions that require a volatile array are allowed to start at the beginning by checking this flag:

 void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) { // snip... CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__); 

Mutable and immutable CFArray identical, except for the transfer or rejection of this statement, and therefore should be NSArray and NSMutableArray , performance or otherwise.

+3
source

Partially answered here: NSArray size and variability

NSMutableArray is not noticeably slower or larger (from memory) than NSArray. This is basically just an NSArray that redistributes itself when it is populated as a more massive array, and continues to do so when you add elements to it.

The reason you copy mutable arrays as immutable when you assign them values ​​in your class is because you can guarantee that their values ​​do not change. If you store a modified array in your class, other code may change its values ​​outside of your class without calling any of your methods. This leaves you vulnerable to crashes due to internal inconsistency errors in your classes.

For example, suppose that when an array was installed, you cached the length of the array as an int property in its class. That would be fine if the array was immutable, but if it was modified, someone else could change the array, and your cached value would now be wrong, but you don't know that.

However, this does not need to be done manually. If you declare the properties of the array as:

 @property (nonatomic, copy) NSArray *foo; 

Then, whenever you assign an object.foo array, it will be automatically copied. You do not need to copy it again. It is best to use the copy property type instead of strong / hold for any type that has a mutable option, for example:

 @property (nonatomic, copy) NSArray *foo; @property (nonatomic, copy) NSString *foo; @property (nonatomic, copy) NSDictionary *foo; @property (nonatomic, copy) NSData *foo; etc... 

However, be careful not to use it for mutable properties, or it will make an immutable copy stored in a property that considers it mutable and causes a crash if you try to mutate it. The synthetic property of the copy is not intelligent enough to automatically use mutableCopy.

 @property (nonatomic, copy) NSMutableArray *foo; //don't do this 
+3
source

For clarity, you ask, can NSArray work with NSArray and NSMutableArray, subjected to a battery of non-mutating test methods, faster? I specify non-mutataing because it looks like you are copying a mutable array into an immutable array, assuming that the immutable array will execute its non-mutating methods faster than the mutated array. In any case, the answer is no. (But do not take my word for it, profile).

Even if NSMutableArray overrides some non-mutating methods (which we cannot know about anyway), you will not need to worry about that. Adding multiple processor cycles is trivial compared to the overall computational complexity of the operation. While the NSMutableArray fails to include the O (n) lookup operation in the O (n 2 ) operation, you will be in order 99% of the time. (These difficulties are just fictitious examples).

While there are well-founded reasons why you would want to copy the modified array into an immutable array (as @NickLockwood pointed out), performance should not be one of them. Premature optimization is very bad, after all.

+2
source

Source: https://habr.com/ru/post/1395279/


All Articles