2013-12-17 6 views
1

У меня есть объект AMContact, где одним из его сильных свойств является массив объектов AMEmailAddress. У одного контакта может быть много адресов электронной почты. Могу ли я создать сильное свойство на моем объекте адреса электронной почты, который указывает на контактный объект?Ребенок, потерявший свою слабую ссылку на родителя

Я чувствую, что если его сильная ссылка может быть циклом удержания. Если я делаю это слабым, когда я делаю свой запрос, чтобы получить все объекты адреса электронной почты, в какой-то момент контактный объект для каждого из них становится нулевым.

- (NSArray*)allEmailAddresses 
{ 
    NSArray *allContacts = [self allContacts]; 
    NSMutableArray *emailAddresses = [NSMutableArray array]; 

    for (AMContact *contact in allContacts) { 
     if (contact.emailAddresses) { 
      for (AMEmailAddress *address in contact.emailAddresses) { 
       [emailAddresses addObject:address]; 
      } 
     } 
    } 
    if (emailAddresses.count > 0) { 
     return emailAddresses; 
    } 
    return nil; 
} 


@interface AMContact : NSObject 

@property (nonatomic, strong) NSString *firstName; 
@property (nonatomic, strong) NSString *lastName; 


// arrays of AMEmailAddress, AMPhoneNumber objects 
@property (nonatomic, strong) NSArray *emailAddresses; 
@property (nonatomic, strong) NSArray *phoneNumbers; 

@end 

@interface AMEmailAddress : NSObject 

@property (nonatomic, strong) NSString *label; 
@property (nonatomic, strong) NSString *email; 
@property (nonatomic, strong) AMContact *contact; // IS THIS OK OR A RETAIN CYCLE? 

@end 
+0

Вы сказали, что «в какой-то момент контактный объект для каждого становится ничем» - когда именно это происходит? В части кода, который вы опубликовали или в другом методе? –

ответ

2

Ответ на короткий вопрос: Могу ли я создать сильное свойство на моем объекте адреса электронной почты, указывающем на контактный объект?

Можете? Да. Тебе следует? Точно нет. Ваш дизайн модели уже намекает на то, какими должны быть отношения - объекты AMContact владеют адресами электронной почты, а не наоборот. Наличие адресов электронной почты имеет сильную ссылку на родительский объект, это не очень хороший способ сделать это. Ссылка от ребенка обратно владельцу должна быть слабой. Тот факт, что ваш экземпляр AMContact подходит к нулю, является проблемой с определением области и дизайном, и вы не должны использовать сильную ссылку, чтобы обойти это.

Что касается того, почему ваш экземпляр AMContact идет nil - это немного странно, потому что если объект AMContact переходит в нуль, его дочерние объекты также должны быть. Это будет нуль в коде, который вы опубликовали, или в каком-то другом месте в каком-то другом методе? Видя код, в котором вы пытаетесь сослаться на него, и это нуль, было бы хорошо.

UPDATE:

Если вы хотите получить список контактов, которые имеют адреса электронной почты, вы должны изменить способ вернуть это. Однако я предполагаю, что вы имеете в виду, что вам нужен список их адресов электронной почты со связанными с ними контактами. В этом случае вам придется перевернуть отношения вокруг и считать, что письмо является родителем, а контакт - ребенком. Обратите внимание: если контакт имеет несколько адресов электронной почты, у вас будет несколько ссылок на один и тот же контакт. Предполагая, что у вас есть contact свойство типа AMContact в вашем AMEmailAddress объекта, я хотел бы добавить строку следующим образом:

for (AMEmailAddress *address in contact.emailAddresses) { 

      //Assign the contact as a property of the email address 
      //Make sure the contact property is strong 
      address.contact = contact; 

      [emailAddresses addObject:address]; 
     } 

//Nil out the emailAddresses array 
contact.emailAddresses = nil; 

UPDATE:

Ok так что теперь вы должны иметь перевернутый объект - emailAddress в качестве родителя и contact как ребенок, без сильной ссылки от contact до emailAddress больше. Это означает, что вы не сможете повторно использовать объект contact, чтобы снова получить адреса электронной почты.Если вам нужно сохранить исходный объект contact как-то, тогда вы правы, вам придется хранить его как свойство в контроллере просмотра или в другом классе - для таких подходов, где мне приходится иметь дело с объектами людей (для того, чтобы пользователи могли приглашать друзей и т. д.) Я использую Singleton «People Manager» и сохраняю там все исходные объекты.

+0

Спасибо за ответ. Я думаю, что происходит в методе allEmailAddresses: я получаю массив всех контактов, нахожу те, у которых есть электронная почта, а затем сохраняю и возвращаю только объекты электронной почты. Никто не сохранит этот оригинальный набор контактов, и поэтому он должен быть нулевым. Как я могу предотвратить это? –

+0

Обновленный ответ - дайте мне знать, если это то, что вы ищете –

+0

Спасибо. Он будет работать в этом случае, но в других случаях мне нужно, чтобы контакты были объектами i vend. Таким образом, в этом случае, похоже, что мой массив адресов электронной почты не является слабым. Решение, которое я пробовал, заключается в том, чтобы выдать массив контактов контроллеру представления, сохранить ссылку на это в свойстве и затем захватить мои объекты электронной почты, используя ту же процедуру, что и выше. Это работает, потому что кто-то поддерживает сильную ссылку на объекты контактов. Недостатком является то, что они занимают некоторую память, которую я не хотел использовать. Это хорошо оформленный дизайн? –

0

Ну в вашем случае, я думаю, что это очень ясно, что контакт является владельцем (родитель) его адресов электронной почты, так что вы будете избегать любых циклов, только проектирования этого соотношения таким образом, то есть, используя слабую обратную ссылку связаться. Если вы используете сильную ссылку, то у вас будет цикл сохранения, потому что NSArray сохраняет своих детей в emailAdresses.

Теперь я бы посмотрел вашу структуру программы, чтобы узнать, как и почему вы теряете контакты в этой слабой ссылке, что-то должно их освобождать, возможно, ваш контакт покидает область действия преждевременно?

Вы можете получить дополнительную информацию и советы по этому вопросу great article о циклах удержания, есть и способы обхода, но я бы посоветовал вам придерживаться дизайна, который имеет больше смысла.

Смежные вопросы