0

I have a set of attributes that are displayed in Tableview through an Array controller (all bindings), I have written some code to change one of the attributes based on the content of others. I wrote this in the .m file that Core data created for this Entity:

header:

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

@class Instrument;

@interface IO : NSManagedObject

@property (nonatomic, retain) NSNumber * channel;
@property (nonatomic, retain) NSString * depiction;
@property (nonatomic, retain) NSString * prefix;
@property (nonatomic, retain) NSNumber * rack;
@property (nonatomic, retain) NSNumber * slot;
@property (nonatomic, retain) NSString * suffix;
@property (nonatomic, retain) NSString * tag;
@property (nonatomic, retain) NSString * type;
@property (nonatomic, retain) NSString * depictionFull;
@property (nonatomic, retain) Instrument *io_instrument;

@end

main:

#import "IO.h"
#import "Instrument.h"
#import "Loop.h"
#import "Area.h"


@implementation IO {
}

@dynamic channel;
@dynamic depiction;
@dynamic prefix;
@dynamic rack;
@dynamic slot;
@dynamic suffix;
@dynamic tag;
@dynamic type;
@dynamic depictionFull;
@dynamic io_instrument;

- (void)awakeFromFetch{

    [self setDepictionFull:[NSString stringWithFormat:@"%@ %@ %@ %@", self.io_instrument.instrument_loop.loop_area.name, self.io_instrument.instrument_loop.depiction, self.io_instrument.depiction, self.depiction]];
}

@end

The are two problems here:

  1. This only changes the table "view" value of my attribute but not the actual saved value (I know this because when I comment-out the code the value does not get saved)

  2. The "awakeFromFetch" function I use only applies the code when I fetch the data but I would also like it to be refreshed when I make a change to any attribute in the entity (or array controller).

Canto
  • 1
  • 1

1 Answers1

0

The best way to do this is not to save a value depictionFull but rather return it when requested.

- (NSString *)dipictionFull {
    return [NSString stringWithFormat:@"%@ %@ %@ %@", self.io_instrument.instrument_loop.loop_area.name, self.io_instrument.instrument_loop.depiction, self.io_instrument.depiction, self.depiction];
}

This way it will always return the newest value, no matter what! It is operating in a lazy way, which iOS and objective-c tend to work well with. This is [generally] not a bad idea to do whenever attributes or properties are completely dependent on other properties or attributes.

As far as the not saving goes: I am guessing the value is displaying correctly and not being saved because you do not explicitly save it.

Lastly, You should not be putting this code into your actual NSManagedObject subclass. What if you add an attribute and need to recreate this class? Then (if you are using XCodes creation tool) it would completely wipe out your custom awakeFromFetch. Instead create a category for IO and put your custom code in there. Then if you need to recreate your NSManagedObject implementation your category goes unchanged.

UPDATE - how to use categories

To create a category go to file - > new -> file (or command+N), then under Cocoa Touch select Objective-C category. Name your category AddOn (or something of the sort) and under Category on put your NSManagedObject's subclass (in this case Instrument). After that is created put the method -(NSString *)dipictionFull; in the .h and the above implementation in the .m. Then when you want to use this method import Instrument+AddOn.h in the class that needs dipictionFull. Then simply call it [self.myInstrument dipictionFull] and you get your string that is always up-to-date because it is pulling the values live every time.

Firo
  • 15,448
  • 3
  • 54
  • 74
  • I understand the value of using the function stated above but my problem is knowing where do I request it. Also, how do I explicitly save something? The reason I placed my code in that object is because I found it was the only place that changed all the corresponding values in my table. My apologies, I am very new to this kind of programming :) – Canto Jun 26 '13 at 00:54
  • @Canto I added some information in my answer, see if that helps you. I am not entirely sure what you are asking so I just guessed. – Firo Jun 26 '13 at 12:47
  • Thanks Firo! I have made the changes you recommended: -Moved the code to a separate Object class -Was able to apply/save changes to my attribute but only to one.. not able to apply the changes to all of the same attribute in an entity. – Canto Jul 04 '13 at 02:57