Re: Stupid objective-c question
Re: Stupid objective-c question
- Subject: Re: Stupid objective-c question
- From: Alastair Houghton <email@hidden>
- Date: Fri, 23 Sep 2016 09:36:08 +0100
On 23 Sep 2016, at 00:19, Sandor Szatmari <email@hidden> wrote:
>
> I wanted to get some opinions on the following which I have done in the past and perceive as different because the string constant is introduced and defined once and only once.
>
> // my .m file
> static NSString * const kMyContext = @"my fantastic context";
>
> // later on
> - (void) observeValueForKeyPath: (NSString *) keyPath ofObject: (id) object
> change: (NSDictionary *) change context: (void *) context
> {
> if ( context == kMyContext )
> { // do my stuff }
> else
> // call super
> }
>
> My interpretation of how to use context has been as an arbitrary pointer... Does this run afoul of anyone's sensibility?
Yes, it’s wrong.
The compiler and linker perform an optimisation known as string coalescing. What this means is that if *anyone* else uses the string @"my fantastic context" in their code and it just happens to get (statically) linked to yours, the address will not be unique. Given the string you picked, it isn’t unlikely that the same string could be used elsewhere as a KVO context.
At present, the risk is confined mainly to your own codebase because string coalescing isn’t performed by the dynamic linker and the system doesn’t intern string constants.
The correct approach is to take *the address of a static variable* and use that, as that’s guaranteed to be unique.
i.e. you need to do this:
static NSString * const kMyContext = @"My fantastic context";
...
[foo addObserver:myObject forKeyPath:@"some.key.path" options:0 context:&kMyContext];
...
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (context == &kMyContext) {
// Do my stuff
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}
Note that you can use *any* type for your variable; in some ways, it might make sense to use a non-pointer type, just to make clear that it’s the address that matters, e.g.
static const int kMyContext = 0xabadf00d;
Otherwise some smart-ass might go and delete the “&” operators from your code, and that makes it vulnerable to problems.
Kind regards,
Alastair.
--
http://alastairs-place.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden