On Aug 20, 2014, at 11:02 PM, Daryle Walker <[email protected]> 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 ([email protected])
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 [email protected]