Custom setter methods in Core-Data

前端 未结 5 1092
夕颜
夕颜 2020-12-07 18:09

I need to write a custom setter method for a field (we\'ll call it foo) in my subclass of NSManagedObject. foo is defined in the data

相关标签:
5条回答
  • 2020-12-07 18:48

    According to the documentation, it'd be:

    - (void) setFoo:(NSObject *)inFoo {
      [self willChangeValueForKey:@"foo"];
      [self setPrimitiveValue:inFoo forKey:@"foo"];
      [self didChangeValueForKey:@"foo"];
    }
    

    This is, of course, ignoring the fact that NSManagedObjects only want NSNumbers, NSDates, NSDatas, and NSStrings as attributes.

    However, this might not be the best approach. Since you want something to happen when the value of your foo property changes, why not just observe it with Key Value Observing? In this case, it sounds like "KVO's the way to go".

    0 讨论(0)
  • 2020-12-07 18:54

    I think there is a slight mistake: use

     [self setPrimitiveValue:inFoo forKey:@"foo"];
    

    instead of

     [self setPrimitiveFoo:inFoo];
    

    this works for me.

    0 讨论(0)
  • 2020-12-07 18:55

    Here is the Apple way for overriding NSManagedObject properties (without breaking KVO), in your .m file:

    @interface Transaction (DynamicAccessors)
    - (void)managedObjectOriginal_setDate:(NSDate *)date;
    @end
    
    @implementation Transaction
    @dynamic date;
    
    - (void)setDate:(NSDate *)date
    {
        // invoke the dynamic implementation of setDate (calls the willChange/didChange for you)
        [self managedObjectOriginal_setDate:(NSString *)date;
    
        // your custom code
    }
    

    managedObjectOriginal_propertyName is a built-in magic method you just have to add the definition for. As seen at bottom of this page What's New in Core Data in macOS 10.12, iOS 10.0, tvOS 10.0, and watchOS 3.0

    0 讨论(0)
  • 2020-12-07 18:57

    Here's how I'm doing KVO on the id attribute of a Photo : NSManagedObject. If the photo's ID changes, then download the new photo.

    #pragma mark NSManagedObject
    
    - (void)awakeFromInsert {
        [self observePhotoId];
    }
    
    - (void)awakeFromFetch {
        [self observePhotoId];
    }
    
    - (void)observePhotoId {
        [self addObserver:self forKeyPath:@"id"
                  options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:NULL];
    }
    
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change
                           context:(void *)context {
        if ([keyPath isEqualToString:@"id"]) {
            NSString *oldValue = [change objectForKey:NSKeyValueChangeOldKey];
            NSString *newValue = [change objectForKey:NSKeyValueChangeNewKey];        
            if (![newValue isEqualToString:oldValue]) {
                [self handleIdChange];
            }
        }
    }
    
    - (void)willTurnIntoFault {
        [self removeObserver:self forKeyPath:@"id"];
    }
    
    #pragma mark Photo
    
    - (void)handleIdChange {
        // Implemented by subclasses, but defined here to hide warnings.
        // [self download]; // example implementation
    }
    
    0 讨论(0)
  • 2020-12-07 19:09

    Here's how you do it 1-n (and I presume n-m) relationships:

    Lets assume the relationship name is called "students" in an object called "School".

    First you need to define the primitive accessor methods for the NSMutableSet. Xcode will not automatically generate these for you.

    @interface School(PrimitiveAccessors)
    - (NSMutableSet *)primitiveStudents;
    @end
    

    Next you can define your accessor method. Here I'm going to override the setter.

    - (void)addStudentsObject:(Student *)student
    {
      NSSet *changedObjects = [[NSSet alloc] initWithObjects:&student count:1];
    
      [self willChangeValueForKey:@"students"
                  withSetMutation:NSKeyValueUnionSetMutation
                     usingObjects:changedObjects];
    
      [[self primitiveStudents] addObject:value];
    
      [self didChangeValueForKey:@"students"
                 withSetMutation:NSKeyValueUnionSetMutation
                    usingObjects:changedObjects];
    }
    
    0 讨论(0)
提交回复
热议问题