ios - 使用复制属性会导致段错误

标签 ios objective-c cocoa-touch

我已经启动了一个 Master Detail 应用程序,并且没有修改生成的代码。我创建并添加了两个额外的类:一个书籍类(包含一个用于标题、作者和摘要的 NSString)和一个数据 Controller 类(包含一个可变数组来存储书籍)。

在阅读 Apple doc 和其他文档后,我对 @property 属性的理解是这样的:

  • strong - 默认,创建对象的所有权
  • weak - strong 的替代品,用于避免保留循环
  • 复制 - 创建现有对象的副本并获得该对象的所有权
  • nonatomic - 无视任何类型的线程安全

  • 当使用 copy 属性声明 @property AJKBook 时,此代码在 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
    

    最佳答案

    如果你想为你的自定义类使用副本,你必须实现 – copyWithZone: 在那些类(class)中。

    但您不必使用 copy .经常strong已经足够好了。 copy主要用于 NSString 属性,因为你想防止 NSMutableString被分配,后来从类外改变。

    您必须考虑是否真的需要复制当前的书。如果某物被命名为 current在我看来,这强烈表明您不想复制。如果唯一的分配来自 [[AJKBook alloc] init];复制根本没有意义。

    关于ios - 使用复制属性会导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19457623/

    相关文章:

    ios - 我可以在一个容器应用程序上创建两个自定义键盘吗

    iOS 本地通知基于日期、时间范围和次数?

    objective-c - 循环遍历 NSStringEncoding(enum) 值

    iphone - SQLite sqlite3_prepare_v2 没有错误但也没有

    ios - 是否可以在 iOS 中原生嵌入推文/推特卡片?

    ios - *** 由于未捕获的异常 'NSInternalInconsistencyException' 而终止应用程序,原因 : 'Tried to pop to a view controller that doesn' t exist. '

    objective-c - MVC 模式 : Where does formatting/processing type work belong?( Objective-C )

    ios - 如何从源代码构建适用于 iOS 的 libssl.a?

    iphone - Objective-C - 基于 eclipse 刻线边界切割图像

    iphone - Mapkit 引脚颜色未改变