Objective-C:使用弱引用

时间:2016-02-20 17:27:43

标签: ios objective-c properties weak

我有几节课: BookPublisherAuthorGenre

所以这是主要的类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

我有委托类 - 类型,所以为了避免强引用周期,Book Genre属性必须

Book.m初始化程序中的这一点:

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

它将为nil,因为Genre实例将在分配后立即解除分配。

根据丹的评论,这是我的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

我的问题是&#34;在属性类型中存储流派对象(genreName - &gt;类型构造函数 - &gt;流派对象)的最佳方法是什么?我如何可以存储它而不使用构造函数来分配弱属性?&#34;。

解决方案:在我的情况下,它是Genre的集合,我将我的弱属性引用带到我的集合中的一个对象。

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]];

3 个答案:

答案 0 :(得分:0)

一种解决方案是使类型属性成为强有力的参考。

如果真的需要让Genre成为弱引用, 您可以通过将所有类型存储在表中并使用以下内容静态访问它来解决此问题:

@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

静态forName方法将在所有类型的表中查找正确的类型。由于将类型存储在表中会保留对象,因此在分配时不会立即释放。

{{1}}

答案 1 :(得分:0)

The rule to remember is - strong properties increase the reference count, while weak ones do not - and when the reference count gets to 0, a proper is deallocated. So in the case of Genre - at your point in the code, there are no strong references to it so it is deallocated. The solution really is to have the Genres 'owned' by another class. This class would manage the genres, creating them and keeping strong references to them, perhaps in for eg an array of Genres. Your 'strong' genre would be passed in with the initializer, and then the weak reference is the correct approach, preventing a retain cycle, but the dealloc is prevented by the strong property that the Genre property already has - does that make sense?

In a way it makes sense to think of your objects as needing an 'owner' class, where strong references are defined that keep them alive. Then when passed to other classes like your Book class, those have weak references, which prevents the retain cycle as you say. The book class isnt the owner, but someone else is - so it doesnt go away.

答案 2 :(得分:0)

弱引用不会创建引用计数。如果只有对象的弱引用,则该对象将被释放。这意味着如果您希望对象保持活动状态,您可以使用强引用,也可以使用强引用将其存储在其他位置。

使用弱引用来避免引用循环,以及此刻在其他地方保留但在某些时候可能会消失的对象。在您的情况下,使用弱引用是您无法正常工作的东西。

相关问题