ABPerson sub-classable?

  • [sorry about the "no subject" post I just made. this is the same post,
    with a subject added]

    Is ABPerson (from the Address Book framework) one of those Cocoa
    classes that shouldn't be sub-classed? How would one go about
    determining something like this? Or is it just one of those things you
    have to "just know"?

    _murat
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Aug 21, 2004, at 8:13 PM, m wrote:

    > Is ABPerson (from the Address Book framework) one of those Cocoa
    > classes that shouldn't be sub-classed? How would one go about
    > determining something like this? Or is it just one of those things you
    > have to "just know"?

    More background:

    I'm trying to use a subclass of ABPerson (from the AddressBook
    framework) as a model class. It's not working.

    If my model class is an NSObject subclass, everything works great. My
    model's accessors get called when my table needs their info. If my
    model class is a subclass of ABPerson, my accessors no longer get
    called and my table shows blank entries, though they're still
    selectable.

    In my test case, here's how I'm declaring my model:

    @interface BTModel : ABPerson
    {
    NSString* modelName;
    }

    - (NSString *)modelName;
    - (void)setModelName:(NSString *)newModelName;

    @end

    Simply changing BTModel  superclass from ABPerson to NSObject makes
    things work as expected. While working around this is easy enough
    (though annoying), I'd like to know why ABPerson subclasses can't
    function as model objects.

    _murat
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • I just tried subclassing ABPerson, and it seemed to work.  Maybe some
    small mistake in your app?  I'll send you my test project off list.

    -Ken

    On Sat, 21 Aug 2004 20:59:34 -0700, m <m0987...> wrote:
    > On Aug 21, 2004, at 8:13 PM, m wrote:
    >
    >> Is ABPerson (from the Address Book framework) one of those Cocoa
    >> classes that shouldn't be sub-classed? How would one go about
    >> determining something like this? Or is it just one of those things you
    >> have to "just know"?
    >
    > More background:
    >
    > I'm trying to use a subclass of ABPerson (from the AddressBook
    > framework) as a model class. It's not working.
    >
    > If my model class is an NSObject subclass, everything works great. My
    > model's accessors get called when my table needs their info. If my
    > model class is a subclass of ABPerson, my accessors no longer get
    > called and my table shows blank entries, though they're still
    > selectable.
    >
    > In my test case, here's how I'm declaring my model:
    >
    > @interface BTModel : ABPerson
    > {
    > NSString* modelName;
    > }
    >
    > - (NSString *)modelName;
    > - (void)setModelName:(NSString *)newModelName;
    >
    > @end
    >
    > Simply changing BTModel  superclass from ABPerson to NSObject makes
    > things work as expected. While working around this is easy enough
    > (though annoying), I'd like to know why ABPerson subclasses can't
    > function as model objects.
    >
    >
    >
    > _murat
    > _______________________________________________
    > cocoa-dev mailing list | <cocoa-dev...>
    > Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    > Do not post admin requests to the list. They will be ignored.
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On Aug 21, 2004, at 10:31 PM, Ken Ferry wrote:

    > I just tried subclassing ABPerson, and it seemed to work.  Maybe some
    > small mistake in your app?  I'll send you my test project off list.

    Subclassing works (this is what you do in your test project). What
    doesn't seem to work is  binding to instances of the subclass.

    You can try it for yourself. I've posted my test project at

    <http://www.muratnkonar.com/source-code/bindingstest.zip>

    In this project, a text field is bound to the "modelName" property of a
    BTModel instance. Three buttons change the value of the BTModel
    instance's "modelName" property.

    Build and run it both ways, one with BTModel as a subclass of NSObject,
    the other with BTModel as a subclass of ABPerson.

    When BTModel is a subclass of NSObject, the bindings perform correctly.
    When BTModel is a subclass of NSPerson, they don't.

    _murat
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • Hello...

    If you use class-dump or otool to check out the methods that ABPerson
    implements, you'll probably find that it  has some sort of manual
    bindings implementation (or more accurately, some type of
    manual/custom key-value coding implementation).

    Either ABPerson or ABRecord probably overrides the default
    implementations of setValue:forKey and valueForKey: and isn't falling
    through to the NSObject implementation for unrecognized keys. If this
    is the case, you'll probably want to file a bug with Apple.

    You can add your own manual KVC in your BTModel class on top of the
    ABPerson implementation to work around the problem...

    - (void)setValue:(id)value forKey:(NSString *)key
    {
    if ([key isEqualToString:@"modelName"])
    {
      [self  setModelName:(NSString *)value];
    }
    else
    {
      [super setValue:value forKey:key];
    }
    }

    - (id)valueForKey:(NSString *)key
    {
    if ([key isEqualToString:@"modelName"])
    {
      return [self  modelName];
    }
    else
    {
      return [super valueForKey:key];
    }
    }

    Hope that helps...

    Louis

    >
    > Subclassing works (this is what you do in your test project). What
    > doesn't seem to work is  binding to instances of the subclass.
    ...
    >
    > When BTModel is a subclass of NSObject, the bindings perform
    > correctly. When BTModel is a subclass of NSPerson, they don't.
    >
    > _murat
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • I tried overriding setValue:forKey: and valueForKey: as Louis
    suggested, no joy. My overrides never get called.

    I've reported this as a bug, # 3771172.

    Cheers, and thanks.

    _murat

    On Aug 22, 2004, at 11:36 AM, Louis C. Sacha wrote:

    > Hello...
    >
    > If you use class-dump or otool to check out the methods that ABPerson
    > implements, you'll probably find that it  has some sort of manual
    > bindings implementation (or more accurately, some type of
    > manual/custom key-value coding implementation).
    >
    > Either ABPerson or ABRecord probably overrides the default
    > implementations of setValue:forKey and valueForKey: and isn't falling
    > through to the NSObject implementation for unrecognized keys. If this
    > is the case, you'll probably want to file a bug with Apple.
    >
    > You can add your own manual KVC in your BTModel class on top of the
    > ABPerson implementation to work around the problem...
    >
    > - (void)setValue:(id)value forKey:(NSString *)key
    > {
    > if ([key isEqualToString:@"modelName"])
    > {
    > [self  setModelName:(NSString *)value];
    > }
    > else
    > {
    > [super setValue:value forKey:key];
    > }
    > }
    >
    > - (id)valueForKey:(NSString *)key
    > {
    > if ([key isEqualToString:@"modelName"])
    > {
    > return [self  modelName];
    > }
    > else
    > {
    > return [super valueForKey:key];
    > }
    > }
    >
    >
    > Hope that helps...
    >
    > Louis
    >
    >
    >>
    >> Subclassing works (this is what you do in your test project). What
    >> doesn't seem to work is  binding to instances of the subclass.
    > ...
    >>
    >> When BTModel is a subclass of NSObject, the bindings perform
    >> correctly. When BTModel is a subclass of NSPerson, they don't.
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
  • On 22. Aug 2004, at 11:55, m wrote:

    > In this project, a text field is bound to the "modelName" property of
    > a BTModel instance. Three buttons change the value of the BTModel
    > instance's "modelName" property.

    If I add the following, the example works:

        - (id)valueForKeyPath:(NSString*)aKey
        {
          if([aKey isEqualToString:@"modelName"])
              return [self modelName];
          return [super valueForKeyPath:aKey];
        }

    Of course that should not be necessary, but you may want to use it as a
    workaround.
    --
        http://macromates.com/
    _______________________________________________
    cocoa-dev mailing list | <cocoa-dev...>
    Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
    Do not post admin requests to the list. They will be ignored.
previous month august 2004 next month
MTWTFSS
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
Go to today