2016-02-20 5 views
0

У меня есть несколько классов: Book, PublisherGenre.Задача-C: работа со слабыми ссылками [Решено]

Так вот главный класс Book.h:

#import "Publisher.h" 
#import "Author.h" 
#import "Genre.h" 

@interface Book : NSObject 

@property (nonatomic, strong) NSString *bookName; 
@property (nonatomic, strong) Author *author; 
@property (nonatomic, strong) Publisher *publisher; 
@property (nonatomic, weak) Genre *genre; 

- (instancetype)initWithBookName:(NSString *)name andAuthorName:(NSString *)authorName 
     andPublisher:(NSString *)publisherName andGenreName:(__strong NSString *)genreName; 
- (NSString *)description; 
@end 

и его реализация Book.m:

#import "Genre.h" 
#import "Book.h" 
#import <Foundation/Foundation.h> 

@implementation Book 

- (instancetype)initWithBookName:(NSString *)name andAuthorName:(NSString *)authorName 
    andPublisher:(NSString *)publisherName andGenreName:(__strong NSString *)genreName{ 
    self = [super init]; 
    if (self) { 
     _bookName = [name copy]; 
     _author = [[Author alloc] initWithAuthorName:authorName]; 
     _publisher = [[Publisher alloc] initWithPublisherName:publisherName]; 
     _genre = [[Genre alloc] initWithGenreName:genreName]; 
    } 
    return self; 
} 

- (instancetype)init { 
    return [self initWithBookName:@"unnamed" andAuthorName:@"unnamed" andPublisher:@"unnamed" andGenreName:@"unnamed"]; 
} 

- (NSString *)description { 
    return [NSString stringWithFormat: @"Book: %@, Author: %@, Genre: %@", self.bookName, self.author, self.genre]; 
} 

@end 

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

На данный момент в инициализаторе Book.m:

_genre = [[Genre alloc] initWithGenreName:genreName]; 

будет ноль, так как экземпляр Genre будет удален сразу после назначения.

Согласно Dan комментарий, вот мой Genre.h:

#import <Foundation/Foundation.h> 
@class Book; 

@interface Genre : NSObject 

@property (nonatomic, strong) NSString *genreName; 
@property (nonatomic, strong) NSArray <Book *> *books; 

- (instancetype)initWithGenreName:(NSString *)name andBooks:(NSArray <Book *>*)books; 
- (instancetype)initWithGenreName:(NSString *)name; 
- (NSString *)description; 

@end 

Мой вопрос: «Что это лучший способ для хранения жанр объект (genreName -> Жанр Конструктор -> жанр объекта) в слабый жанр свойств и как его сохранить, не используя конструктор для назначения слабому свойству? ".

Спасибо всем, кто обратился за помощью.

РЕШЕНИЕ: В моем случае это была коллекция Жанра, и я беру ссылку на мою слабую собственность на один из объектов из моей коллекции.

Genre * genre1 = [[Genre alloc]initWithGenreName:@"Comedy"]; 
Genre * genre2 = [[Genre alloc]initWithGenreName:@"Drama"]; 
Genre * genre3 = [[Genre alloc]initWithGenreName:@"Fantastic"]; 
Genre * genre4 = [[Genre alloc]initWithGenreName:@"National"]; 

NSArray <Genre*> *genres = @[genre1, genre2, genre3, genre4]; 
Book *book1 = [[Book alloc] initWithBookName:@"Book #3!" andAuthorName:@"Grinch Burs" andPublisher:@"Ableton" andGenre:[genres objectAtIndex:0]]; 
+0

В коде, который вы опубликовали, ничего не говорится о том, что вы должны сделать свойство 'genre' слабым – dan

+0

@dan Я добавил Genre.h, не могли бы вы посмотреть его снова? – Oracle

+0

Самая большая проблема, которую я вижу, состоит в том, что в «Жанре» должна быть коллекция книг внутри него. Я бы сделал «Жанр» более легким. Вы можете иметь массив всех книг и фильтровать их по жанру, когда это необходимо. Не нужно сохранять предварительно отфильтрованные книги. – Sulthan

ответ

0

правило, чтобы помнить, - сильные свойства увеличивают количество ссылок, в то время как слабые не - и когда счетчик ссылок становится равным 0, правильное освобождается. Поэтому в случае с жанром - в вашей точке кода нет сильных ссылок на него, поэтому он освобождается. Решение действительно состоит в том, чтобы иметь жанры «другого». Этот класс управлял бы жанрами, создавал их и поддерживал бы крепкие ссылки на них, возможно, для, например, массива жанров. Ваш «сильный» жанр будет передан с инициализатором, а затем слабая ссылка - правильный подход, предотвращающий цикл сохранения, но dealloc предотвращается сильным свойством, которое уже имеет свойство Genre, - это имеет смысл?

В некотором смысле имеет смысл думать о ваших объектах как о необходимости класса «владелец», где определены сильные ссылки, которые сохраняют их. Затем, когда они передаются другим классам, таким как ваш класс Book, у них есть слабые ссылки, которые препятствуют сохранению цикла, как вы говорите. Класс книги не является владельцем, но кто-то другой - так что он не уходит.

0

Одним из решений было бы сделать свойство жанра сильной ссылкой.

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

_genre = [Genre forName:genreName] 

Статический метод forName бы затем посмотрите правильный жанр в таблице всех жанров. Поскольку сохранение жанра в таблице сохранит объект, оно не будет немедленно выпущено при назначении.

@implementation Genre 
static NSDictionary* genres; 
+ (void) initGenres { 
    // initialize the dictionary and insert all genres 
    // or just initalize the dictionary and insert genres on demand 
} 
+ (Genre*) forName: (NSString*) genreName { 
    if (!genres) { 
     [Genre initGenres]; 
    } 
    //lookup the genre in the dictionary and return it 
} 
@end 
+0

Я сделал это, но он все еще не работает. Он работает только тогда, когда я использую режим отладки. – Oracle

+0

Что именно не работает? – Palle

0

Слабая ссылка не создает счетчик ссылок. Если есть только слабые ссылки на объект, объект будет освобожден. Это означает, что если вы хотите, чтобы объект оставался в живых, вы либо используете сильную ссылку, либо хранилище в другом месте, используя сильную ссылку.

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

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