1

マスター詳細アプリケーションを開始しましたが、生成されたコードはそのままにしておきました。2 つの追加クラスを作成して追加しました。書籍クラス (タイトル、著者、概要の NSString を含む) とデータ コントローラー クラス (書籍を格納する可変配列を含む) です。

Apple doc などを読んだ後の @property 属性に関する私の理解は次のとおりです。

  1. strong - デフォルト、オブジェクトの所有権を作成します
  2. weak - strong の代わりに使用され、保持サイクルを回避するために使用されます
  3. copy - 既存のオブジェクトのコピーを作成し、その所有権を取得します
  4. 非アトミック - あらゆる種類のスレッドセーフを無視します

@property AJKBook が copy 属性で宣言されている場合、このコードは addBookToList でセグメンテーション違反をスローしますが、その理由はわかりません。

@interface AJKBookDataController ()

// when current book uses the copy attribute code seg faults in addBookToList
@property (nonatomic) AJKBook  *currentBook;
@property (nonatomic, copy) NSString *currentValue;

- (void)populateBookList;
- (void)addBookToBookList;

@end

@implementation AJKBookDataController

- (id)init
{
    self = [super init];
    if (self) {
        _bookList = [[NSMutableArray alloc] init];
        _currentBook = [[AJKBook alloc] init];
        _currentValue = [[NSString alloc] init];
        [self populateBookList];
        return self;
    }
    return nil;
}

- (void)setBookList:(NSMutableArray *)bookList
{
    // this bit of code ensures bookList stays mutable
    if (_bookList != bookList) {
        _bookList = [bookList mutableCopy];
    }
}

- (void)populateBookList
{
    NSURL *url = [NSURL URLWithString:@"https://sites.google.com/site/iphonesdktutorials/xml/Books.xml"];

    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];

    [parser setDelegate:self];
    [parser parse];

    NSLog(@"%@", [self.bookList description]);
}

- (void)addBookToBookList
{
    [self.bookList addObject:self.currentBook];
    self.currentBook = [[AJKBook alloc] init];
}
...
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"title"]) {
        // [self.currentBook title:self.currentValue];
        self.currentBook.title = self.currentValue;
    } else if ([elementName isEqualToString:@"author"]) {
        self.currentBook.author = self.currentValue;
    } else if ([elementName isEqualToString:@"summary"]) {
        self.currentBook.summary = self.currentValue;
    } else if ([elementName isEqualToString:@"Book"]) {
        [self addBookToBookList];
    }

    self.currentValue = [NSString stringWithFormat:@""];
}
@end
4

1 に答える 1

3

カスタム クラスにコピーを使用する場合は– copyWithZone:、それらのクラスに実装する必要があります。

ただし、使用する必要はありませんcopy。多くstrongの場合、十分です。copyは主に NSString プロパティに使用されます。これは、 aNSMutableStringが割り当てられ、後でクラスの外部から変更されることを防ぐためです。

現在の本を本当にコピーする必要があるかどうかを考える必要があります。私の意見で名前が付けられている場合、それはcurrentコピーしたくないという強い兆候です。唯一の割り当てが[[AJKBook alloc] init];コピーからのものである場合、まったく意味がありません。

于 2013-10-18T19:32:19.453 に答える