首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何观察ABPersonView对ABPerson的更改

如何观察ABPersonView对ABPerson的更改
EN

Stack Overflow用户
提问于 2015-09-17 15:14:44
回答 1查看 124关注 0票数 0

我知道ABPersonView不是KVO的投诉对象。我的问题是,尽管每次访问属性时都保留了ABPersonView的声明属性,但我得到了不同的对象。我做错了什么吗?还是说每次ABPersonView发生变化,我都必须用新的ABPerson对象更新模型?使用埃尔卡皮坦通用汽车公司。

ABPersonView:

代码语言:javascript
复制
@property (readwrite, retain) ABPerson *person;
// An ABPerson record for display.
// Raises if person originates from ABAddressBook's +sharedAddressBook.
// Person must be exist in an ABAddressBook created and manipulated on the main thread only.
// When person is nil, displays an empty selection state. 

代码:

代码语言:javascript
复制
#import "AppDelegate.h"
@import AddressBook;
static void * ABPersonVCContext = &ABPersonVCContext;

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (strong) ABPerson *person;
@property (strong) ABPersonView *personView;
@property (strong) ABAddressBook *book;
@property (assign, getter=isEditing) BOOL editing;
@property NSTimer *timer;
@end

@implementation AppDelegate

- (instancetype)init {
  self = [super init];
  if (self) {
    _book = [[ABAddressBook alloc] init];
    NSString *vCardRepresentation = @"BEGIN:VCARD\r\nVERSION:3.0\r\nN:AA;BB;;;\r\nFN:\r\nEND:VCARD\r\n";
    NSData *vCardData = [vCardRepresentation dataUsingEncoding:NSUTF8StringEncoding];
    _person = [[ABPerson alloc] initWithVCardRepresentation:vCardData];
    [_book addRecord:_person];
    [self addObserver:self forKeyPath:@"editing"
              options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
              context:ABPersonVCContext];
#ifdef DEBUG
    NSLog(@"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__);
    NSLog(@"%@",_person);
#endif
  }
  return self;
}

- (void)awakeFromNib
{
  self.personView = [[ABPersonView alloc] initWithFrame:self.window.contentView.frame];
  self.personView.person = self.person;
  [self.window.contentView addSubview:self.personView];
  self.timer = [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(reverseEditing) userInfo:NULL repeats:YES];
  [self.timer fire];
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
  if (context == ABPersonVCContext) {
    if ([keyPath isEqualTo:@"editing"]) {
#ifdef DEBUG
      NSLog(@"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__);
      NSLog(@"%@",self.personView.person);
#endif
    }
  } else {
    @try {
      [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
    @catch (NSException *exception) {
      ;
    }
    @finally {
      ;
    }
  }
}

- (void)reverseEditing
{
  self.editing = !self.editing;
}

@end

编辑:新对象来自不同的addressBook实例:

代码语言:javascript
复制
(lldb) po [newPerson addressBook]
<ABAddressBook: 0x6080000d50e0>

(lldb) po self.book
<ABAddressBook: 0x6080000c4130>

(lldb) po [self.person addressBook]
<ABAddressBook: 0x6080000c4130>

EDIT2:即使注册通知也没有帮助,因为正在修改不同的对象。

代码语言:javascript
复制
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(changeOccured:) name:kABDatabaseChangedNotification object:nil];
[nc addObserver:self selector:@selector(changeOccured:) name:kABDatabaseChangedExternallyNotification object:nil];
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-09-17 18:55:56

不幸的是,每次调用personView的person属性都会触发将CNContact转换为ABPerson的ABPersonViewAPIAdapter。因此,如果不想在El Capitan上使用CNContact,他必须将经过编辑的ABPerson传播回模型对象。

您可以尝试使用以下代码(希望这将为某人节省一些时间)

代码语言:javascript
复制
  NSLog(@"%@",[self.personView performSelector:@selector(addressBook) withObject:nil]);
  NSLog(@"%@",[self.personView performSelector:@selector(_APIAdapter) withObject:nil]);
  NSLog(@"%@",[self.personView performSelector:@selector(_contact) withObject:nil]);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32633990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档