What's the best way to use Obj-C 2.0 Properties with mutable objects, such as NSMutableArray?

后端 未结 6 1032
逝去的感伤
逝去的感伤 2020-11-30 11:13

I have an Obj-C 2.0 class that has an NSMutableArray property. If I use the following code, then the synthesised setter will give me an immutable copy, not a mutable one:

相关标签:
6条回答
  • 2020-11-30 11:53

    Keep in mind that passing around a mutable array isn't really a common practice in Cocoa. You might use a private mutable array as internal storage, but create methods using plain NSArray objects to add or get objects out of it. This may be why there's no mutablecopy property declaration.

    0 讨论(0)
  • 2020-11-30 11:55

    As said before, the right way to do it is not to make the mutable array a property. There's a great explanation of what you should implement to be KVC compliant here.

    0 讨论(0)
  • 2020-11-30 11:56

    The right way to hold on to a NSMutableArray is with a retain property:

    @property (nonatomic, retain) NSMutableArray *myArray;
    

    You do not need to write your own setter or use copy. The copy property should be used with a NSArray that actually does need to be copied when the property is captured into another object. For example, if you assign a NSMutableArray object to a property that is of type NSArray with the copy property, then you do want to make a copy of the mutable array to "capture" it as an immutable property from that point forward.

    And Marc has the right approach, one would not normally make NSMutableArray a part of the public API of your objects. If you do have a public property, it can be a NSArray with the copy property.

    0 讨论(0)
  • 2020-11-30 11:57

    It's not common to pass around NSMutableArrays in Cocoa. Standard Cocoa practice would be to implement the key-value coding compliant methods for an indexed to-many property. This has two benefits:

    1. Key-value observing works as expected (there are several cases where observing an NSMutableArray leads to not-what-you-want behavior)
    2. The implementation of your data structure is hidden because you expose mutating methods (e.g. -[MyObject insertObjectInMyProperty:(id)newObject atIndex:(NSUInteger)i] , not the data structure itself.
    0 讨论(0)
  • 2020-11-30 12:01

    I ran into the same problem some time ago and found a document on the Apple Developer Connection recommending to provide your own implementation of the setter. Code sample form the linked document:

    @interface MyClass : NSObject {
        NSMutableArray *myArray;
    }
    @property (nonatomic, copy) NSMutableArray *myArray;
    @end
    
    @implementation MyClass
    
    @synthesize myArray;
    
    - (void)setMyArray:(NSMutableArray *)newArray {
        if (myArray != newArray) {
            [myArray release];
            myArray = [newArray mutableCopy];
        }
    }
    
    0 讨论(0)
  • 2020-11-30 12:05

    You'll have to write your own setter.

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