adding non-persistent variables to nsmangedobject - objective-c

I have a subclass of an NSManagedObject, and I'd like to add a couple ivars to keep track of some book-keeping. I don't want these vars to persist, and so that is why I don't include them as part of the data model.
I'm having trouble finding the proper way of doing this.
should I just create ivars in my class, create the corresponding property and then synthesis them in the implementation?
should I not create ivars, and instead just declare the property and then #dynamic the property in the implmentation?
is there some other approach i should be taking?
And should I be doing all the customization in the my NSManagedObject subclass, or should I be creating a subclass of my subclass, so that if I change my data model I won't lose all my customizations when I get xcode to generate my NSManagedObject subclass automatically?
Thanks!

Each attribute for NSManagedObject has a checkbox named transient. This way you'll have dynamic accessors for the object without actually persisting the property value itself. Look for checkbox right under the text field for attribute name entry.
UPDATE If you don't want to create a migration because of new attributes, make standard ivars
#interface MyMO : NSManagedObject {
NSString *_nonPersistentAttribute;
}
#property (nonatomic, retain) NSString *nonPersistentAttribute;
#end
#implementation MyMO
#synthesize nonPersistentAttribute=_nonPersistentAttribute;
#end

The documentation for NSManagedObject has a section called Custom Instance Variables. It discusses both approaches.
Both transient, modeled attributes and ivars are good solutions. It depends on taste and style.
One very important point to remember if you use ivars: You need to clear out ivars in - (void)didTurnIntoFault and set any initial values in - (void)awakeFromFetch and - (void)awakeFromInsert. You need to not touch any modeled attributes or relationships inside -didTurnIntoFault or else you'll get in trouble.

Wise,
To your first question re: ivars, you have two choices standard ivars or transient attributes on your entity. The big difference between the two is that the transient attributes participate in the change/dirty/undo aspects of Core Data. If your ivars don't need that, then don't use the transient attributes. (Yes, use #property and #synthesize for your ivars.)
To your second question re: where to make the changes? I am somewhat of a luddite. The header patterns automatically generated by Xcode are pretty simple. Hence, I use the auto generated files for the first time I create an entity and edit in my changes thereafter. Frankly, you don't change your model data structures very often. Hence, adding a few lines here and there to both .h&.m files isn't a big cost. There are other mechanisms. Wolf Rentzch's mogenerator system is well respected and useful. That said, I'm not convinced that mogenerator solves a problem faced by modern Objective-C v2 Core Data programmers. (Obj-C v2 has made many things easier for Core Data programmers.)
Andrew

Here is a convenient pattern I have used in the past:
Create a category of your class and put it into an additional source file, such as ManagedObject+Support.h. Remember, in the interface declaration you just use brackets like this:
#interface ManagedObject (Support)
// declare your variables and methods
#end
In this way, you can change things around without having to modify your managed object model. (Changing the MOM has many issues with repopulated databases, migration, etc.). When you change the model, you can generate the class files again without loosing the code in the category.

Related

Difference between self.name and _name using modern Objective-C

Say this is in my header file:
#interface AppDelegate : NSObject <NSApplicationDelegate>
#property (weak) IBOutlet NSSlider *slider;
- (void)doSomething;
#end
…and this is the *m:
#implementation AppDelegate
- (void) doSomething {[self.slider setFloatValue:0];}
#end
I'm new to Xcode and Objective C, and I would like to use and understand the modern “tools” presented by Apple in its documentation, namely ARC, or here more specifically the ability to skip #synthesize.
If I understood correctly, #property (weak) IBOutlet NSSlider *slider; does a few things for me, including:
creating an instance variable called _slider;
creating a getter named slider;
creating a setter named setSlider.
I've been doing C++ until now, so I see instance variables as the equivalent of what I am calling (rightly, I hope) members of my C++ classes, which I incidentally always call _member.
I understand that the whole point of encapsulation is that, if you're outside a given class, you have to use accessors to access those variables; they are private to you, so there's no way you can access them via _member even if you tried.
But, when I'm writing my *.m file of my class, _member means something. Back to my example, I think self.slider and _slider are equivalent. The latter comes naturally to mind first, as it saves a few character.
My question is: are the two absolutely equivalent?
I know this looks similar to this question, for example, but here’s a few reasons why I wanted to ask myself:
I don’t use #synthesize, so I’m really not the one creating _slider, and I wonder if this makes a difference (I believe this is a fairly recent improvement of ObjC, and most answers still refer to #synthesize);
it seems that on average, most conversations end up with “so, just use self.name”, but I don’t grasp if this is just a recommendation, a convention, of something more important (with an impact on, say, the performance);
similarly, some say you should only use _name in methods like dealloc and its friends; but I don’t write those thanks to ARC, so does this mean I should never use _name? If so, why?
I hope this justifies this post, I apologies if I missed a preexisting answer. Thanks in advance for your help.
self.name = compiles to [self setName:] this is very different then setting the variable directly.
One of the main reasons that using the default setter differs deals with key value observing often referred to as KVO. Using the setter will notify observers of changes, setting the _name directly will not.
Thats not to say you can't fire the events your self with willChangeValueForKey: and didChangeValueForKey:, but the default implementation will handle that for you. So as you say outside the class accessing them you have to use the property get/set but inside your class setting the variable directly will lose out on some notifications. I'm sure there are other differences this is the first that comes to mind.
Using the variable directly does have it's use cases, such as a custom property setter. I think the main take away is the dot syntax is a hidden function call to get/set.
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/Articles/KVOCompliance.html
Under basic circumstances, where you use the pre-made accessors, you could probably get away with using _slider or self.slider within your class interchangeably. They're not equivalent in how they compile necessarily, but the functionality could be said to be equivalent.
The bigger issue comes into play when you start overriding those accessors. When those accessors do more than just "getting" or "setting" a variable, such as accessing some sort dependency variable, accessing the instance variable directly bypasses that functionality that the accessors provide. In these cases, I don't think it can be said that the two are equivalent at all.

Is it possible to extend(heritance) class in Objective-c as is traditionally conceptualised in other languages?

I am having a lot of repeated code throughout my app classes given that some properties & method are stable across all my views.
I am looking to extend whatever class I am working with so that it automatically inherit all properties and methods that I think should be common to those classes.
I looked into the apple guide on extending classes. But I am left confused in the terms of the level of heritance that I can achieve.
I've successfully created Categories on lets say a UIViewController. But that limits me to only be able to declare Methods. I can not declare Properties on my Category and call them in side my Category or in the Extended Class. I want to be able to declare Properties and use it inside and outside my Extended-Class.
Its my first time trying to extend a class in objective-c taking full advantage of heritance but I do not know if it is possible. Am I missing something?
As an example in the code below every time I try to instantiate activityIndicatorView inside my method _activityIndicator it wouldn't recognise it. I've tried #syntetize and #dynamic but it doesn't work
NOTE: I am seeking an answer based on how to achieve heritance of methods and propeties. not highlighting what categories cant do (as I already tried and know I cant have properties there)
My attempt went as far of
#import <UIKit/UIKit.h>
#interface UIViewController (customViewController1)
#property (strong, nonatomic) UIView *activityIndicatorView;
- (void) _activityIndicator;
#end
#import "UIViewController+customViewController1.h"
#implementation UIViewController (customViewController1)
- (void) _activityIndicator {
//......
}
Your question is too broad, plus it is not clear what your problem is. Yes, you can subclass in Objective-C.
This is all very well documented in Apple's document "Object-Oriented Programming with Objective-C", section "The Object Model", subsection "Inheritance".
Categories are a nice way to add functionality while at the same time conforming to an object oriented principle to prefer composition over inheritance.
Categories only add methods, you can't add variables to a class using categories. If the class needs more properties, then it has to be subclassed.
When you use the term “extend”, you're talking about creating a subclass. This is, IIRC, how the term is used in Java and some other languages.
Apple uses the term differently (as Hermann Klecker hinted in his first comment). They literally mean extending an existing class with more functionality (in the form of methods)—that's what categories do. This is the normal English definition; extending something in the real world generally does not create a new thing.
Objective-C supports subclasses, too; it just doesn't call them “extending” the superclass. It's called creating a subclass, which inherits from the superclass.
Strctly spoken you cannot add a property to an existing class any differnt than creating a subclass.
If you cannot halp yourself and subclassing is not an option, then you can extend the class with getters and setters for the property that you want to store within the class.
Instead of really storing it as a member/instance variable/property, which you can't do, you could store the object (it cannto be a scalar, must be an object) in the global space using objc_setAssociatedObject(id object, void *key, id value, objc_AssociationPolicy policy).
This is some sort of global dictionary with two keys, the key itself and the ojbect to which you want to associat the stored object to. In your case that is the object of the type of the exended class. The setter stores it there and the getter receives it from there using objc_getAssociatedObject.
You delete an association by sending nil as value to objc_setAssociatedObject
AFAIK retained associated objects (values) are released shortly after the object that holds the associateion (object) is deallocated.
For further details see the Ojbective-C Runtime Reference https://developer.apple.com/library/ios/documentation/Cocoa/Reference/ObjCRuntimeRef/Reference/reference.html
Just: I do not say that this is strictly following the OO paradigm. :-)

Where does the add(Propertyname) method come from?

I'm using the following lines to declare a property in my objective-c program.
#property (retain) int Money;
and the syntesize in my implementation file.
Now i wanted to make an addMoney method in my implementation to add an amount of money in my program. I was typing addMoney when i realized that Xcode was saying there is always a method with this name that i could override. It has the following signature.
-(void)addMoney:(NSSet *)objects;
and
-(void)addMoneyObject:(object-type *)object
where do they come from and who is calling them? AND how could i use it by myself? What must i attend to when using this?
This method does not actually exist. Xcode is helping you out by completing some common naming patterns. It's somewhat common to have a situation like this:
#class Thing;
#property (nonatomic, retain) NSMutableSet *things;
- (void)addThings:(NSSet *)someThings;
- (void)addThing:(Thing *)aThing;
Xcode is just trying to make it a little easier to type that. But the methods don't really exist unless you create them.
Side note: you can't retain an int, so I assume this isn't real code. That's fine. Do make sure your properties start with a leading lowercase (money). It's not just individual style. ObjC relies on Key-Value Coding for many things. That requires that things be named in a certain way or it won't work.
Is Money a ManagedObject (Core Data object)? If so, that method may be being created for you. Synthesized properties should provide setter and getter but that method would look like -(void)setMoney:(int)money and -(int)Money

Data encapsulation...?

Would anyone be able to explain to me what data encapsulation in Objective-C is? I've been told that this an important concept of Objective-C but I don't see why...
Explain it to me as if I was 5 and then as if I was 25....
Thanks for your time,
~Daniel
From http://mobile.tutsplus.com/tutorials/iphone/learn-objective-c-2/ :
What we mean by data encapsulation is
that data is contained (so to speak)
by methods meaning to access it we
need to use methods. Some of you who
have programmed in other languages and
havenʼt heard of data encapsulation
may be wondering why we do things this
way. The answer is that by
encapsulating data, there is a nice
cushion between the developer of a
class and the user of a class. Because
the class methods manage and maintains
the attributes within the class, they
can more easily maintain data
integrity. Another major benefit is
that when a developer distributes his
class, the people using it donʼt have
to worry about the internals of the
class at all. A developer may update a
method to make it faster or more
efficient, but this update is
transparent to the user of the class
as he/she still uses the same method
with no change to his/her code.
In simple terms, the user is provided with what the developer wanted them to have, and "protects" everything else. The developer can change anything internal without the user having to rewrite their code.
If developers did not conform to data encapsulation, we would need to rewrite our code every time a new version of a library, code snippet, or an entire program was released.
Data encapsulation in Objective-C means that only the class itself should touch it's instance variables. Therefor you should always mark them as private, and only expose them through properties, as this:
#interface Foo : NSObject {
#private
int numberOfBars;
Baz* contentBaz;
}
#property(nonatamic, assign) int numberOfBars;
#property(nonatomic, retain) Baz* contentBaz;
#end
This means that the class can implement validation in it's setter methods. And even better if you use #synthesizeto generate your getter and setters than you need not even worry about the memory model of Cocoa at all (with the exception of releasing your ivars in dealloc).

Avoiding #property-itis (i.e. overuse of properties, when are they appropriate)?

Objective-C 2.0 gave us #properties.
They allow for introspection.
They allow for declarative programming.
The #synthesize and #dynamic mechanisms relieve use from having to write repetitive, stock accessors.
Finally, there is the ‘dot’ property syntax, which some love, and some hate.
That isn't what I'm hear to ask. Like any new feature, there is an initially tendency to want to use #property everywhere. So where is property use appropriate?
Clearly in model objects, attributes and relationships are good fodder for properties.
#property(...) NSString *firstName;
#property(...) NSString *lastName;
#property(...) Person *parent;
Even synthesized/computed attributes seem like a good use case for properties.
#property(...) NSString *fullName;
Where else have you used properties? Where have you used them, then later decided it was an inappropriate use of the feature?
Do you use properties for your private object attributes?
Can you think of any examples of things which aren't properties in Cocoa, which at first look, seem like they might want to be properties, but after closer inspection, are actual an example of abuse or property-itis?
My recommendation to people is to use property's wherever possible. If you are working in a framework, the ability to use non-fragile instance variables in the modern runtime is a huge bonus and if you aren't, properties make it clear how your ivars are to be managed (assigned vs retained vs copied). There isn't an inherent performance loss from declaring a property other than the time it takes to write the line of code (I actually use a TextExpander snippet to do this for me) but the potential for preventing bugs is large enough that it becomes a fantastic best-practice. If you do plan to user properties for private ivars, you can do so inside your implementation file via an #interface block. For example
#interface MyObject()
#property(retain) NSArray *myArray;
#end
If I had to think of a reason to avoid them, I'd say don't use it for computed attributes where the computation involved is significant. Properties encourage code like:
if (foobar.weight > 100) {
goober.capacity = foobar.weight;
}
In this example, foobar.weight is called twice. If it's just returning a cached value, no problem. But if it needs to block the thread while it deploys a robot to manually weigh the foobar each time, the above snipped of code would waste two robot deployments when only one is needed.
In such cases, I'd recommend NOT using a property, and also naming the method differently, so that the code would look more like:
int w = [foobar computeWeight];
if (w > 100) {
goober.capacity = w;
}
With a name like computeWeight it is easier to remember that it is a long running operation.
I would avoid using properties if the accessor method does something non-obvious to the object, like setting an unrelated instance variable. Also if the property being returned doesn't really "belong" to the object. For instance, in one of my projects I have a stringValue method that I decided not to make a property for this reason. This is really more a matter of style though.