1

私はいくつかのクラスを持っています: BookPublisherAuthorおよびGenre.

メイン クラス 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

私はデリゲート クラス - Genre を持っているので、強い参照サイクルを避けるために、 aBookGenreプロパティはweakでなければなりません。

Book.m イニシャライザのこの時点で:

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

Genreインスタンスは割り当て直後に割り当て解除されるため、nil になります。

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 のコレクションであり、弱いプロパティ参照をコレクションのオブジェクトの 1 つに取得します。

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

3 に答える 3

1

覚えておくべきルールは、強力なプロパティは参照カウントを増やしますが、弱いプロパティは増加させません。参照カウントが 0 になると、適切なプロパティの割り当てが解除されます。したがって、ジャンルの場合、コードのあなたの時点では、それへの強い参照がないため、割り当てが解除されます。解決策は、ジャンルを別のクラスに「所有」させることです。このクラスは、ジャンルを管理し、それらを作成し、それらへの強力な参照を維持します。たとえば、ジャンルの配列などです。あなたの「強い」ジャンルはイニシャライザで渡され、弱い参照は正しいアプローチであり、保持サイクルを防ぎますが、Genre プロパティがすでに持っている強いプロパティによって解放が妨げられます-それは意味がありますか?

ある意味では、オブジェクトを「所有者」クラスが必要であると考えるのは理にかなっています。そこでは、オブジェクトを存続させる強力な参照が定義されています。次に、 Book クラスなどの他のクラスに渡されると、弱い参照が含まれるため、保持サイクルが妨げられます。book クラスは所有者ではありませんが、他の誰かが所有者であるため、消えません。

于 2016-02-20T19:48:51.587 に答える
0

弱参照は参照カウントを作成しません。オブジェクトへの弱い参照しかない場合、オブジェクトは割り当て解除されます。つまり、オブジェクトを存続させたい場合は、強参照を使用するか、強参照を使用して別の場所にオブジェクトを保存します。

弱い参照を使用して、参照サイクルを回避し、現在は別の場所に保持されているが、ある時点で消える可能性があるオブジェクトに使用します。あなたの場合、弱い参照を使用すると、適切に機能しなくなります。

于 2016-02-20T23:04:17.640 に答える