How to observe (KVO) count change in an NSMutableArray [duplicate] - objective-c

I'd like to be notified, when the count, ie. number of items in an NSArray changes..
Of course I wouldn't need this, if I was in control of addition and removal of objects into the array. But I am not, it happens unpredictably with regards to Business Process Model and depends on external factors.
Is there some simple elegant solution?
EDIT: I am correcting this to NSMutableArray of course..

You’ll need to use KVC. But how to go about doing it? After all, NSMutableArray is not Key-Value-Coding compliant for its mutation methods or contents changes. The answer is proxying –as subclassing NS[Mutable]Array is far too much of a hassle.
NSProxy is a great little class that you can use to intercept the messages sent to your array as though you were an NSMutableArray, then forward them on to some internal instance. Unfortunately, it is also not KVC compliant, as the guts of KVC live in NSObject. We’ll have to use that, then. A sample interface might look something like this:
#interface CFIKVCMutableArrayProxy : NSObject {
NSMutableArray *_innerArray;
}
- (NSUInteger)count;
- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
- (void)removeObjectAtIndex:(NSUInteger)index;
- (void)addObject:(id)anObject;
- (void)removeLastObject;
- (void)insertObjects:(NSArray *)objects atIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
//…
#end
As you can see, we’re simulating an interface for NSMutableArray, which is necessary, as our proxy should implement everything as though it were an NSMutableArray. This also makes the implementation as simple as possible, as we can just forward the selectors on to our inner NSMutableArray pointer. For the sake of brevity, I’ll only implement two methods to show you what a general outline looks like:
#implementation CFIKVCMutableArrayProxy
//…
- (NSUInteger)count {
return _innerArray.count;
}
- (void)addObject:(id)anObject {
[self willChangeValueForKey:#"count"];
[_innerArray addObject:anObject];
[self didChangeValueForKey:#"count"];
}
- (void)removeLastObject {
[self willChangeValueForKey:#"count"];
[_innerArray removeLastObject];
[self didChangeValueForKey:#"count"];
}
#end
If you have no opportunities to wrap an array like this, then try to re-think your code. If an external dependency is forcing you into this kind of corner, try to remove it. It’s always a bad thing to work around your own tools.

To observe changes in a mutableArray one needs to use mutable proxy object given by
- (NSMutableArray *)mutableArrayValueForKey:(NSString *)key
which is KVO compliant, i.e. any change of proxy object sends will/did change notifications.
The following demo class shown the full implementation
#interface DemoClass : NSObject
#property (nonatomic) NSMutableArray *items;
- (void)addItemsObserver:(id)object;
- (void)removeItemsObserver:(id)object;
#end
#implementation DemoClass
- (NSMutableArray *)items;
{
return [self mutableArrayValueForKey:#"_items"];
}
- (void)addItemsObserver:(id)object
{
[self addObserver:object forKeyPath:#"_items.#count" options:NSKeyValueObservingOptionOld|NSKeyValueObservingOptionNew context:nil];
}
- (void)removeItemsObserver:(id)object
{
[self removeObserver:object forKeyPath:#"_items.#count" context:nil];
}
#end
#interface ObservingClass : NSObject
#property (nonatomic) DemoClass *demoObject;
#end
#implementation ObservingClass
- (instanstype)init
{
if (self = [super init]) {
_demoObject = [DemoClass new];
[_demoObject addItemsObserver:self];
}
return self;
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
NSLog(#"is called on demoObject.items.count change");
}
- (void)dealloc
{
[_demoObject removeItemsObserver:self];
}
#end
Now every time you add or remove an object in the items you'll see new log in console (observeValueForKeyPath is called).
Any direct change of auto-synthesised ivar _itemsarray will have no effect.
Also note that you strongly need to set the observer on _items.#count (observing items.#count is senseless).
Note that you needn't to init _items or self.items. It will be done behind the scene when you call items getter.
Every time you change the "array" items you will get new object _items with new address. But I can still find it via items proxy getter.

Related

Delegation to multiple objects

Is there any way to delegate to two objects at a time in Objective-C? I know that delegation pattern implies one response at a time and for multiple listeners and broadcasting there is notification center but notification does not return any value.
If I have a heavily network-based iOS project and need to delegate to multiple listeners and required to return values from them, in this scenario what approach should be the best?
In every class the delegate is one, so one delegate is informed about the event. But nothing forbids you to declare a class with a set of delegates.
Or use Observation instead. A class may be observed by multiple classes.
Example
As requested from the OP, since also some code would be useful, here is a way of doing it:
#interface YourClass()
#property (nonatomic, strong, readwrite) NSPointerArray* delegates;
// The user of the class shouldn't even know about this array
// It has to be initialized with the NSPointerFunctionsWeakMemory option so it doesn't retain objects
#end
#implementation YourClass
#synthesize delegates;
... // other methods, make sure to initialize the delegates set with alloc-initWithOptions:NSPointerFunctionsWeakMemory
- (void) addDelegate: (id<YourDelegateProtocol>) delegate
{
[delegates addPointer: delegate];
}
- (void) removeDelegate: (id<YourDelegateProtocol>) delegate
{
// Remove the pointer from the array
for(int i=0; i<delegates.count; i++) {
if(delegate == [delegates pointerAtIndex: i]) {
[delegates removePointerAtIndex: i];
break;
}
} // You may want to modify this code to throw an exception if no object is found inside the delegates array
}
#end
This is a very simple version, you can do it in another way. I don't suggest to make public the delegates set, you never know how it could be used, and you can get an inconsistent state, specially with multithreading. Also, when you add/remove a delegate you may need to run additional code, so that's why making the delegates set private.
You may also a lot of other methods like delegatesCount for example.
PS: The code has been edited to be a NSPointerArray instead of a NSMutableSet, because as stated in the comments a delegate should be held with a weak pointer to avoid retain cycles.
In addition to Ramys answer you could use a [NSHashTable weakObjectsHashTable] instead of a
NSMutableSet. This would keep only a weak reference to your delegates and prevents you from running into memory leaks.
You will get the same behavior you already know from standard weak delegates #property (nonatomic, weak) id delegate;
#interface YourClass()
#property (nonatomic, strong) NSHashTable *delegates;
#end
#implementation YourClass
- (instancetype)init
{
self = [super init];
if (self) {
_delegates = [NSHashTable weakObjectsHashTable];
}
return self;
}
- (void) addDelegate: (id<YourDelegateProtocol>) delegate
{
// Additional code
[_delegates addObject: delegate];
}
// calling this method is optional, because the hash table will automatically remove the delegate when it gets released
- (void) removeDelegate: (id<YourDelegateProtocol>) delegate
{
// Additional code
[_delegates removeObject: delegate];
}
#end
Robbie Hanson wrote a multicast delegate implementation. Looks like what you need. He talks about it in more detail here, and how it is used in the XMPPFramework. He has some good discussion about one of the main problems which is how to handle the case where the multiple delegates implement a given method who's return value determines the class' behaviour (and the multiple delegates return different values). Relevant bits:
What is a MulticastDelegate?
The xmpp framework needs to support an unlimited number of extensions.
This includes the official extensions that ship with the framework, as
well as any number of extensions or custom code you may want to plug
into the framework. So the traditional delegate pattern simply won't
work. XMPP modules and extensions need to be separated into their own
separate classes, yet each of these classes needs to receive delegate
methods. And the standard NSNotification architecture won't work
either because some of these delegates require a return variable.
(Plus it's really annoying to extract parameters from a notification's
userInfo dictionary.)
So a MulticastDelegate allows you to plug into the framework using the
standard delegate paradigm, but it allows multiple classes to receive
the same delegate notifications. The beauty of this is that you don't
have to put all your xmpp handling code in a single class. You can
separate your handling into multiple classes, or however you see fit.
If you're writing the function that will call the delegates, you can have as many as you want. But if you're using a class (that you can't change) that calls the delegates, then you can't have more delegates than the class supports.
You could, if it worked out for you, have one delegate call another. Set up the first delegate so it will call the second delegate (whose pointer is stored in the first delegate object). This can be simple, with it pre-defined as to which calls are "passed on", or quite complex, using the dynamic call mechanisms of Objective-C.
One delegate can be setting for only one object but it's possible to store delegates in array.
Variant of Ramy Al Zuhouri is good but I want to say that it may be a problem to release delegates from array because NSArray (like NSMutableArray) classes retain all added objects but delegate in most cases is an assign property without retainCount. Retaining the delegate can bring to consequences that class with delegate implementation will have retainCount + 1.
Solution of this is store delegates in NSMutableArray like pointers to delegate methods.
I'm using singletone class with delegate header.
//YourClass.h file
#protocol YourDelegateProtocol <NSObject>
-(void)delegateMethod;
#end
#interface YourClass : NSObject
+(YourClass *)sharedYourClass;
- (void) addDelegate: (id<YourDelegateProtocol>) delegate;
- (void) removeDelegate: (id<YourDelegateProtocol>) delegate
#end
//YourClass.m file
#interface YourClass()
#property (nonatomic, retain) NSMutableArray *delegates;
-(void)runAllDelegates;
#end
#implementation YourClass
#synthesize delegates = _delegates;
static YourClass *sharedYourClass = nil;
+(YourClass *)sharedYourClass {
if (!sharedYourClass || sharedYourClass == nil) {
sharedYourClass = [YourClass new];
sharedYourClass.delegates = [NSMutableArray array];
}
return sharedYourClass;
}
-(void)addDelegate: (id<YourDelegateProtocol>) delegate{
NSValue *pointerToDelegate = [NSValue valueWithPointer:delegate];
[_delegates addObject: pointerToDelegate];
}
-(void)removeDelegate: (id<YourDelegateProtocol>) delegate{
NSValue *pointerToDelegate = [NSValue valueWithPointer:delegate];
[_delegates removeObject: pointerToDelegate];
}
-(void)runAllDelegates{
//this method will run all delegates in array
for(NSValue *val in sharedYourClass.delegates){
id<YourDelegateProtocol> delegate = [val pointerValue];
[delegate delegateMethod];
}
}
-(void)dealloc{
sharedYourClass.delegates =nil;
[sharedYourClass release], sharedYourClass =nil;
[super dealloc];
}
#end
//YourClassWithDelegateImplementation.h file
#include "YourClass.h"
#interface YourClassWithDelegateImplementation : NSObject <YourDelegateProtocol>
#end
//YourClassWithDelegateImplementation.m file
#implementation YourClassWithDelegateImplementation
-(id)init{
self = [super init];
if(self){
//...your initialization code
[[YourClass sharedYourClass] addDelegate:self];
}
return self;
}
-(void)delegateMethod{
//implementation of delegate
}
-(void)dealloc{
[[YourClass sharedYourClass] removeDelegate:self];
[super dealloc];
}
#end
If you want to call callbacks for classes B and C from a class A with only one delegate, you could create a delegate wrapper DWrap which has references to the classes B and C. Then class A calls the callbacks on B and C through DWrap.

How do you determine if an object (self) with a lot of properties has been changed?

The short version of the question:
I have a class with a ton of declared properties, and I want to keep track of whether or not there have been any changes to it so that when I call a save method on it, it doesn't write to the database when it isn't needed. How do I update an isDirty property without writing custom setters for all of the declared properties?
The longer version of the question:
Let's say that I have a class like this:
#interface MyObject : NSObject
{
#property (nonatomic, retain) NSString *myString;
#property (nonatomic, assign) BOOL myBool;
// ... LOTS more properties
#property (nonatomic, assign) BOOL isDirty;
}
...
#implementation MyObject
{
#synthesize myString;
#synthesize myBool;
// ... LOTS more synthesizes :)
#synthesize isDirty;
}
Attempt 1
My first thought was to implement setValue:forKey: like this:
- (void)setValue:(id)value forKey:(NSString *)key {
if (![key isEqualToString:#"isDirty"]) {
if ([self valueForKey:key] != value) {
if (![[self valueForKey:key] isEqual:value]) {
self.isDirty = YES;
}
}
}
[super setValue:value forKey:key];
}
This works perfectly until you set the value directly with a setter (i.e. myObject.myString = #"new string";), in which case setValue:forKey: isn't called (I'm not sure why I thought that it would be, lol).
Attempt 2
Observe all properties of self.
- (id)init
{
// Normal init stuff
// Start observing all properties of self
}
- (void)dealloc
{
// Stop observing all properties of self
}
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
// set isDirty to true
}
I'm pretty sure that this will work, but I think that there must be a better way. :)
I also want this to be automatic, so that I don't have to maintain a list of properties to watch. I can easily see forgetting to add a property to the list when maintaining this down the road and then trying to figure out why my object sometimes doesn't get saved.
Hopefully I'm overlooking a much simpler approach to this problem!
Final Solution
See my answer below for my final solution to this. It is based on the answer provided by Josh Caswell, but is a working example.
A little introspection should help out here. The runtime functions can give you a list of all the object's properties. You can then use those to tell KVO that dirty is dependent on that list. This avoids the maintainability problem of having to update the list of properties by hand. The one caveat is that, like any other solution involving KVO, you won't be notified if the ivar is changed directly -- all access must be through setter methods.
Register to observe self's dirty key path in init, and add this method, creating and returning an NSSet with the names of all the class's properties (except #"dirty", of course).
#import <objc/runtime.h>
+ (NSSet *)keyPathsForValuesAffectingDirty
{
unsigned int num_props;
objc_property_t * prop_list;
prop_list = class_copyPropertyList(self, &num_props);
NSMutableSet * propSet = [NSMutableSet set];
for( unsigned int i = 0; i < num_props; i++ ){
NSString * propName = [NSString stringWithFormat:#"%s", property_getName(prop_list[i])];
if( [propName isEqualToString:#"dirty"] ){
continue;
}
[propSet addObject:propName];
}
free(prop_list);
return propSet;
}
Now an observation of dirty will be triggered whenever any of this class's properties are set. (Note that properties defined in superclasses are not included in that list.)
You could instead use that list to register as an observer for all the names individually.
It may be a bit overkill depending on your needs, but CoreData provides everything's needed to manage object states and changes. You can use a memory based data store if you do not want to deal with files, but the most powerful setup uses SQLite.
So then, your objects (based on NSManagedObject) will inherit a handful of useful methods, like -changedValues which lists the changed attributes since the last commit or -committedValuesForKeys: nil which returns the last committed attributes.
Overkill possibly, but you do not have to reinvent the wheel, you do not need to use a third party library, and it will need only a few lines of code to make it work nicely. Memory usage will be impacted quite a fair bit, but not necessarily for the bad if you choose to use a SQLite datastore.
Core Data apart, using KVO is the way to go to implement your own snapshot mechanism or change manager.
My final solution (Thanks Josh Caswell for the example!):
- (id)init
{
if (self = [super init])
{
[self addObserver:self forKeyPath:#"isDirty" options:0 context:NULL];
}
return self;
}
- (void)dealloc
{
[self removeObserver:self forKeyPath:#"isDirty"];
}
- (BOOL)loadData
{
// Load the data, then if successful:
isDirty = NO;
return YES;
}
- (BOOL)saveData
{
if (!self.isDirty)
{
return YES;
}
// Save the data, then if successful:
isDirty = NO;
return YES;
}
// isDirty is dependant on ALL of our declared property.
+ (NSSet *)keyPathsForValuesAffectingIsDirty
{
unsigned int num_props;
objc_property_t *prop_list = class_copyPropertyList(self, &num_props);
NSMutableSet * propSet = [NSMutableSet set];
for( unsigned int i = 0; i < num_props; i++ )
{
NSString * propName = [NSString stringWithFormat:#"%s", property_getName(prop_list[i])];
if(![propName isEqualToString:#"isDirty"] )
{
[propSet addObject:propName];
}
}
free(prop_list);
return propSet;
}
// If any of our declared properties are changed, this will be called so set isDirty to true.
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:#"isDirty"])
{
isDirty = YES;
}
}
I don't know what all of your properties are, but you could try "superclassing" them. Create an object ObservedObjectand then make custom classes for all of your objects that are subclasses of this object. Then either put an isDirty property on ObservedObject and look at it, or send a notification to your program when it is changed. This might be a lot of work if you have many different types of objects, but if you have mostly many of the same object it shouldn't be too bad.
I'm interested to see if this is a viable solution or if a good solution can be found for this kind of problem.
One option would be in your save method to get the old version myObject and do something like
if (![myOldObject isEqual:myNewObject]) {
//perform save
}

What is best practice to interaction with object in objective-c?

My questions is next:
For example I have object A (this is data model object). Assume that object A have some property (for example request property). Also I have object B (this is my view object).
So my problem is next: when my data model will be changed (the value for request property changed) I want to know about this events in my view (object B)
How to create this interaction between object.
For example in request is written to "some_value" and after this object B immediately know about it.
Thanks for response!
You can use delegation pattern, NSNotifications, callback blocks and even KVO. Choice depends on situation, in your case delegate or callback block would work.
I would use Key Value Observing. Your view controller (not the view itself) would set itself up as an observer for the data model object and when it gets observer notifications, it would update the view.
[myDataObject addObserver: myViewController
forKeyPath: #"request"
options: NSKeyValueObservingOptionNew
context: nil];
// in the view controller you need
-(void) observeValueForKeyPath: (NSString*) path
ofObject: (id) aDataObject
change: (NSDictionary*) changeDictionary
context: (void*) context]
{
if (aDataObject == myDataObject
&& [path isEqualToString: #"request"])
{
// change you are interested in
}
// Call suoer implementation of this method if it implements it
}
Don't forget to remove the observer when you are done with it.
Also, be careful in a threaded environment. Observations are notified on the same thread that the change happens on. If this is not the main thread, you'll need to use -performSelectorOnMainThread:withObject:waitUntilDone: to make any changes to the UI.
If you just want object B to know whats up I would suggest using delegation.
If maybe later you want object C, D and E to know too what happend in object A i would suggest using NSNotification.
For example I have class DataModel. In this step I add observer for my property str. For object I will send my view controller.
.h
#import <Foundation/Foundation.h>
#interface DataModel : NSObject
#property (strong, nonatomic) NSString *str;
- (void)setUpObserver:(id)object;
#end
.m
#import "DataModel.h"
#implementation DataModel
#synthesize str;
- (void)setUpObserver:(id)object
{
[self addObserver:object forKeyPath: #"str" options: NSKeyValueObservingOptionNew context: nil];
}
#end
In my view controller
#import "DataModel.h"
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
dm = [[DataModel alloc] init];
[dm setUpObserver:self];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if (object == dm && [keyPath isEqualToString: #"str"])
{
NSLog(#"it's work");
}
}
- (IBAction)changeValue:(id)sender {
dm.str = #"test change value";
}
#end
This is my realization of KVO. Thanks JeremyP for explanation.

Is subclassing NSNotification the right route if I want to add typed properties?

I am trying to subclass NSNotification.
Apple's docs for NSNotificationstate the following:
NSNotification is a class cluster with no instance variables. As such,
you must subclass NSNotification and override the primitive methods
name, object, and userInfo. You can choose any designated initializer
you like, but be sure that your initializer does not call
NSNotification’s implementation of init (via [super init]).
NSNotification is not meant to be instantiated directly, and its init
method raises an exception.
But this isn't clear to me. Should I create an initializer like this?
-(id)initWithObject:(id)object
{
return self;
}
Subclassing NSNotification is an atypical operation. I think I've only seen it done once or twice in the past few years.
If you're looking to pass things along with the notification, that's what the userInfo property is for. If you don't like accessing things through the userInfo directly, you could use a category to simplify access:
#interface NSNotification (EasyAccess)
#property (nonatomic, readonly) NSString *foo;
#property (nonatomic, readonly) NSNumber *bar;
#end
#implementation NSNotification (EasyAccess)
- (NSString *)foo {
return [[self userInfo] objectForKey:#"foo"];
}
- (NSNumber *)bar {
return [[self userInfo] objectForKey:#"bar"];
}
#end
You can also use this approach to simplify NSNotification creation. For example, your category could also include:
+ (id)myNotificationWithFoo:(NSString *)foo bar:(NSString *)bar object:(id)object {
NSDictionary *d = [NSDictionary dictionaryWithObjectsForKeys:foo, #"foo", bar, #"bar", nil];
return [self notificationWithName:#"MyNotification" object:object userInfo:d];
}
If, for some strange reason, you'd need the properties to be mutable, then you'd need to use associative references to accomplish that:
#import <objc/runtime.h>
static const char FooKey;
static const char BarKey;
...
- (NSString *)foo {
return (NSString *)objc_getAssociatedObject(self, &FooKey);
}
- (void)setFoo:(NSString *)foo {
objc_setAssociatedObject(self, &FooKey, foo, OBJC_ASSOCIATION_RETAIN);
}
- (NSNumber *)bar {
return (NSNumber *)objc_getAssociatedObject(self, &BarKey);
}
- (void)setBar:(NSNumber *)bar {
objc_setAssociatedObject(self, &BarKey, bar, OBJC_ASSOCIATION_RETAIN);
}
...
It seems this does work. For example:
#import "TestNotification.h"
NSString *const TEST_NOTIFICATION_NAME = #"TestNotification";
#implementation TestNotification
-(id)initWithObject:(id)object
{
object_ = object;
return self;
}
-(NSString *)name
{
return TEST_NOTIFICATION_NAME;
}
-(id)object
{
return object_;
}
- (NSDictionary *)userInfo
{
return nil;
}
#end
also beware a massive Gotcha related to NSNotifications. The type of NSNotifications greated using NSNotification notificationWithName:object: is NSConcreteNotification, not NSNotification. And to make it a little more awkward, if you are checking for class, NSConcreteNotification is private so you have nothing to compare to.
You don’t set it, exactly—you just override the implementation of the name method so it returns what you want. In other words:
- (NSString *)name
{
return #"Something";
}
Your initializer looks fine—I haven’t seen an example of an init that doesn’t call its superclass’s implementation before, but if that’s what the doc’s saying you should do, it’s probably worth a try.
You can pass a userInfo argument when delivering a notification. Why not create a payload and send that.
// New file:
#interface NotificationPayload : NSObject
#property (copy, nonatomic) NSString *thing;
#end
#implementation NotificationPayload
#end
// Somewhere posting:
NotificationPayload *obj = [NotificationPayload new];
obj.thing = #"LOL";
[[NSNotificationCenter defaultCenter] postNotificationName:#"Hi" object:whatever userInfo:#{ #"payload": obj }];
// In some observer:
- (void)somethingHappened:(NSNotification *)notification
{
NotificationPayload *obj = notification.userInfo[#"payload"];
NSLog(#"%#", obj.thing);
}
Done.
As a side note: I've found over the years that making a conscious effort to avoid subclassing has made my code more clean, maintainable, changeable, testable and extensible. If you can solve the problem using protocols or categories then you wont lock yourself into the first shoddy design you come up with. With Swift 2.0 protocol extensions in the mix we're really laughing too.

Responding to setters

What is the best way to respond to data changes when property setters are called. For example, if I have a property called data, how can I react when [object setData:newData] is called and still use the synthesised setter. Instinctively, I would override the synthesised setter like so:
- (void)setData:(DataObject *)newData {
// defer to synthesised setter
[super setData:newData];
// react to new data
...
}
...but of course this doesn't make sense - I can't use super like this. So what is the best way to handle this situation? Should I be using KVO? Or something else?
There are a few different ways to do this, depending on how much control you want. One way to do it is to observe your own property:
[self addObserver:self forKeyPath:#"data" options:0 context:nil];
- (void)observeValueForKeyPath:(NSString *)path ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if(object == self && [path isEqualToString:#"data"]) {
//handle change here
} else [super observeValueForKeyPath:path ofObject:object change:change context:context];
}
Make sure you remove yourself as an observer in your dealloc or finalize method, if not before.
Another way would be to override -didChangeValueForKey:. However, this method may not be called if there are no observers on the object.
- (void)didChangeValueForKey:(NSString *)key {
[super didChangeValueForKey:key];
if([key isEqualToString:#"data"]) {
//handle change here
}
}
#synthesize creates default accessors for easy use. In case some special action is needed then it is always possible to write own accessors instead of using #synthesize. The setter and getter are not inherited from base class, they are created by the #synthesize directive. So you don't need to (neither you can) call super setData: (unless you really have created super class that support that).
Just ensure that you are managing memory correctly. Memory Management Programming Guide contains examples on how to manage memory for different types of memory policy (retain or assign or copy).
From this SO answer.
You can define a synthesized "private" property, (put this in your .m file)
#interface ClassName ()
// Declared properties in order to use compiler-generated getters and setters
#property (nonatomic, strong <or whatever>) NSObject *privateSomeObject;
#end
and then manually define a getter and setter in the "public" part of ClassName (.h and #implementation part) like this,
- (void) setSomeObject:(NSObject *)someObject {
self.privateSomeObject = someObject;
// ... Additional custom code ...
}
- (NSArray *) someObject {
return self.privateSomeObject;
}
You can now access the someObject "property" as usual, e.g. object.someObject. You also get the advantage of automatically generated retain/release/copy, compatibility with ARC and almost lose no thread-safety.