On Aug 20, 2014, at 11:02 PM, Daryle Walker <dary...@mac.com> wrote:

> I’m writing an NSOperation subclass. Instances are dumped into the main 
> queue, but I hope I stop them from executing right away by overriding 
> -isReady. But the docs say I have to keep the override KVO-compliant. And my 
> formula for the new -isReady uses the old one. Can I observe on super?

"super" refers to the same object as "self".  There's no separate thing to 
observe.

"super" is not a pointer to an object, actually.  It's only valid as a receiver 
of a message invocation and the only thing it does is modify the dispatch of 
that message.  It modifies how the runtime searches for a method implementation 
for that message.  In particular, the search starts with the methods 
implemented by the superclass of the code into which the super keyword was 
compiled, skipping over any methods supplied by the current class and any 
subclasses.

(More specifically, a message to super translates into a call to one of the 
objc_msgSendSuper*() functions rather than objc_msgSend*().  But the specified 
receiver is the same exact pointer.  For objc_msgSendSuper*(), the receiver is 
passed indirectly in a struct, but, still, it's the same object pointer.)


It follows that super doesn't have separate attributes from self.  If the 
superclass modifies one of its attributes, it's modifying the object's 
attributes, period.  If it does so in a KVO-compliant manner, it will emit KVO 
change notifications.  This is indistinguishable to observers from when your 
subclass modifies them.


>> + (NSSet *)keyPathsForValuesAffectingIsReady {
>>    return [NSSet setWithObjects:@"super.isReady", @"cancelledFiles", 
>> @"failedFiles", @"successfulFiles", nil];
>> }

"super" is not a key – it doesn't name a property – so it has no place in a key 
path.  It also makes no sense.  This is saying the isReady property depends on 
the isReady property.  (Remember, there's no separate object.  super is just a 
reference to self.)

So, you need to drop the "super.isReady" pseudo-key-path.

However, there's a problem with your method.  If a superclass implements 
+keyPathsForValuesAffectingIsReady or +keyPathsForValuesAffectingValueForKey: 
which checks for @"isReady", then you would mask that and break stuff.

You might be tempted to fix that by invoking [super 
keyPathsForValuesAffectingIsReady], but you can't be sure that the superclass 
used that form of the method.

Then, you might be tempted to invoke [super 
keyPathsForValuesAffectingValueForKey:@"isReady"].  The problem there is that a 
superclass may have implemented +keyPathsForValuesAffectingIsReady.  In that 
case, it will be relying on the NSObject implementation of 
+keyPathsForValuesAffectingValueForKey: turning around and invoking 
+keyPathsForValuesAffectingIsReady for that key.  But how would NSObject's 
implementation invoke that?  It will send it to self (the class object, since 
these are class methods).  But that will invoke your implementation again.  
You'll get infinite recursion.

So, I think the only safe approach when you're overriding a property is to 
override +keyPathsForValuesAffectingValueForKey: and not 
+keyPathsForValuesAffectingIsReady.  In your override, you pass through to 
super.  Then, you check if the key is @"isReady" and, if it is, add your key 
paths.


>> - (BOOL)isReady {
>>    return [super isReady] && (self.cancelledFiles.count + 
>> self.failedFiles.count + self.successfulFiles.count >= files.count);
>> }

> Are my key paths for my own attributes correct?

Yes.

> Can I point to an attribute from super with “super.whatever”?

No and it's not necessary.  If the superclass changes what its implementation 
of -isReady returns, then it must emit KVO change notifications since it 
promised in its design contract that that property is KVO-compliant.  Those 
change notifications reach the same observers and have the same meaning as ones 
you would emit yourself.

> Can I really trigger my ready flag with just indirect observations on the 
> four attributes I need?

Yes.  You don't show any mutation of the "files" property.  I'm assuming it is 
set during initialization and never changes after that.  If that's correct, 
then it's KVO-compliant and you're good.

Regards,
Ken


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to