Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 目标C:与弱参考文献一起工作_Ios_Objective C_Properties_Weak - Fatal编程技术网

Ios 目标C:与弱参考文献一起工作

Ios 目标C:与弱参考文献一起工作,ios,objective-c,properties,weak,Ios,Objective C,Properties,Weak,我有几门课: 书籍,出版商,作者和流派 这是主要的课堂教材。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) Pu

我有几门课:
书籍
出版商
作者
流派

这是主要的课堂教材。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
以及他的实施手册。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
它将为零,因为
类型
实例将在分配后立即解除分配

@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
根据Dan comment,以下是我的类型。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
#导入
@教材;
@接口类型:NSObject
@属性(非原子,强)NSString*genreName;
@属性(非原子、强)NSArray*书籍;
-(instancetype)initWithGenreName:(NSString*)名称和书籍:(NSArray*)书籍;
-(instancetype)initWithGenreName:(NSString*)名称;
-(NSString*)说明;
@结束
我的问题是“在弱属性类型中存储类型对象(genreName->genre constructor->genre object)的最佳方式是什么?如何在不使用构造函数分配给弱属性的情况下存储它?”

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

解决方案:在我的例子中,它是一个类型集合,我将我的弱属性引用带到集合中的一个对象。

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]];
Genre*genre1=[[Genre alloc]initWithGenreName:@“喜剧”];
流派*genre2=[[Genre alloc]initWithGenreName:@“戏剧”];
Genre*genre3=[[Genre alloc]initWithGenreName:@“奇妙”];
Genre*genre4=[[Genre alloc]initWithGenreName:@“National”];
NSArray*genres=@[genre1,genre2,genre3,genre4];
Book*book1=[[Book alloc]initWithBookName:@“Book#3!”和作者姓名:@“Grinch Burs”和出版商:@“Ableton”和流派:[流派对象索引: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时,将释放一个适当的属性。因此,在类型的情况下,在代码中,没有对它的强引用,因此它被释放。真正的解决办法是让另一个类“拥有”这些类型。这个类将管理这些类型,创建它们并保留对它们的强引用,例如一系列类型。您的“强”类型将与初始值设定项一起传递,然后弱引用是正确的方法,可以防止保留循环,但是dealloc被类型属性已经具有的强属性所阻止-这有意义吗


在某种程度上,将对象视为需要一个“所有者”类是有意义的,在这个类中定义了强引用以保持它们的活动性。然后,当传递到其他类(如Book类)时,这些类具有弱引用,这会阻止您所说的保留周期。book类不是所有者,但其他人是所有者-因此它不会消失。

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


您可以使用弱引用来避免引用循环,也可以用于此时处于其他位置但可能在某个点消失的对象。在您的情况下,使用弱引用是无法正常工作的

您发布的代码中没有任何内容建议您使用
类型
属性weak@dan我添加了流派。h,你能再看一遍吗?我看到的最大问题是
流派
里面应该有一本书。我会使
类型
更轻量级。您可以拥有所有书籍的数组,并在需要时按流派对其进行筛选。不需要保存预过滤的书籍。@Sulthan但是如果我必须使用这个弱属性,我如何才能使用它当前的结构?@Oracle你做得对,你只需要在某个地方保存流派数组。我做了,但它仍然不起作用。它只在我使用调试模式时工作。