• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: self registering NSValueTransformer and bindings
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: self registering NSValueTransformer and bindings


  • Subject: Re: self registering NSValueTransformer and bindings
  • From: Torsten Curdt <email@hidden>
  • Date: Thu, 8 May 2008 12:53:36 +0200


On May 7, 2008, at 19:32, I. Savant wrote:

I have a self registering NSValueTransformer that requires a binding.

Did you mean it's required for use in a binding?

Well, maybe it's language barrier as a non-native speaker ...but in order for the transformer to do its job it requires a reference to the NSTabView to be set. And I was trying to inject that reference through a binding. That's what I wanted to say.


@interface MyValueTransformer : NSValueTransformer {
   IBOutlet NSTabView *tabView;
}

That's probably not going to work out ... (see below)

// from http://www.gigliwood.com/weblog/
+ (void)load
{
   NSLog(@"registered %@", NSStringFromClass([self class]));

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSValueTransformer *theTransformer = [[[self alloc] init] autorelease];
[NSValueTransformer setValueTransformer:theTransformer
forName:NSStringFromClass([self class])];
[pool release];
}

See: http://developer.apple.com/documentation/Cocoa/Conceptual/ValueTransformers/Concepts/Registration.html

Read that :)

 Here you're instantiating an instance of the generic
NSValueTransformer class and letting the NSValueTransformer class know
that it should use that generic transformer any time
"MyValueTransformer" is requested.

That does not seem to be true. But to be 100% sure I've changed it to

NSValueTransformer *theTransformer = [[[MyValueTransformer alloc] init] autorelease];

...and still get the same behavior. The correct instance is always a MyValueTransformer and no NSValueTransformer as you said.

I've instantiate it through the NIB. Which works fine! I do see the NSLog
lines and all.

I'm not sure how that's happening, given the above. I would expect your transform method not to be called at all, given the above. I could be wrong, then again it's not working right for you, so it's worth checking out. ;-)

No, that's all working fine. See above.

Unfortunately the IBOutlet stays nil ...but in the bindings inspector I can
see the proper binding on the transformer.

I don't know what you mean about 'the proper binding', but no, I wouldn't expect the outlet to be anything but nil. The *instance* you *instantiated* in your nib is not the same one you're passing when registering the transformer for the name "MyValueTransformer". In *that* instance, the outlet is nil.

Doh! ...now here I was really stupid. But then again I would think changing it to


- (void) awakeFromNib
{
    NSLog(@"registered %@", NSStringFromClass([self class]));

[NSValueTransformer setValueTransformer:self forName:NSStringFromClass([self class])];
}


would solve it. Turns out this is not enough. From looking at the stacktrace it seems like the framework seems to create another instance. So the only way I could get it to work was to register the transformer in the init.

- (id) init
{
    self = [super init];

    if (self != nil) {
        NSLog(@"new %@ (%@)", NSStringFromClass([self class]), self);

[NSValueTransformer setValueTransformer:self forName:NSStringFromClass([self class])];
}


    return self;

}

This way I end up just with the one instance created from the NIB.

 Perhaps in some -awakeFromNib method you could ask
NSValueTransformer for the transformer for the name
"MyValueTransformer" and set its outlet then (you'd need a 'setter'
accessor method) ... but what you're doing is strange.

A value transformer really shouldn't know anything about a tab view.

Well, that depends ...see below

Its sole job is to transform one value to another. A number to a
string, or a class name to an image, etc. and possibly vice-versa
(reverse transformations). Why does yours care about a tab view?
Perhaps all you want is a few constants that's included into your
transformer via a header include ...

That is one way and I've already got it working like that.

...

That header can be included in your
AccountTypeToSelectedTabTransformer ... where it gives the correct tab
index depending on whether the passed value is kNormalAccountType or
kSuperHappyFunLuckyMegaAccountType or some other ridiculous example.
Keeps everything simple, straight-forward, and easy to read months
later when you decide to modify it.

Well, my account types have declarative names instead of defined numbers. So the transformer basically does


- (id)transformedValue:(id)value
{
    if ([@"accountType1" isEqualToString:value]) {
        return [NSNumber numberWithInt:1];
    }
    ...

And I think this could be quite neatly be abstracted away if the transformer had access to the NSTabView. The name of the tab would be the name of the account type the transformer is mapping to. Not such a weird idea IMO. But it requires the transformer to have a reference to the NSTabView. I could manually inject it - but using a NIB and using bindings felt more natural (to me). It would make the transformer much more re-usable ...so I was trying

I wouldn't expect the reference to be set in awakeFromNib ....but I would expect it to be set later on when transformedValue is getting called. And that actually seems to work fine now :-D

Does that make a little more sense now?


One thing that is still missing is to get multiple instances working. So basically getting rid of "NSStringFromClass([self class])" and replace that with data from the object's interface builder identity. But somehow I doubt that's easily accessible ...is it?


cheers
--
Torsten

_______________________________________________

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


  • Follow-Ups:
    • Re: self registering NSValueTransformer and bindings
      • From: "I. Savant" <email@hidden>
References: 
 >self registering NSValueTransformer and bindings (From: Torsten Curdt <email@hidden>)
 >Re: self registering NSValueTransformer and bindings (From: "I. Savant" <email@hidden>)

  • Prev by Date: How to send email without using email client
  • Next by Date: Re: Saving only required files in a file wrapper?
  • Previous by thread: Re: self registering NSValueTransformer and bindings
  • Next by thread: Re: self registering NSValueTransformer and bindings
  • Index(es):
    • Date
    • Thread