موضوعية - ج-C صفيف من كائنات سوء التصرف (exc_bad_access) في TableviewController

StackOverflow https://stackoverflow.com/questions/758895

سؤال

أنا جديد على الهدف - ج، ولا يمكنني معرفة سبب إطلاق كائنات NSSTRING في صفيف كائنات سيارتي قد تم إصدارها.

إليك فئة سيارتي:


#import "Car.h"
@implementation Car
@synthesize categoryId;

- (id)initWithPrimaryKey:(NSInteger)pk categoryId:(NSNumber *)catId carName:(NSString *)n {
    if (self = [super init]) {
        primaryKey = pk;
        categoryId = catId;
        name = n;
    }

    return self;
}
- (void)dealloc {
    [name release];
    [categoryId release];

    [super dealloc];
}
- (NSInteger)primaryKey {
    return primaryKey;
}
- (NSString *)name {
    return name;
}
- (void)setName:(NSString *)aString {
    if ((!name && !aString) || (name && aString && [name isEqualToString:aString])) return;
    [name release];
    name = [aString copy];
}

@end

وهنا فئة بلدي simple_tableviewcontroller.m. يتم تعيين متغير مثيل ListData بشكل صحيح في ViewDIDLoad (). في المصحح، فإن خاصية NSSTRING * اسم عنصر صفيف سليم. ثم، في كل طريقة أخرى، ListData تالف. لديها كل عناصر السيارة مع قيم المهمة والفئات الصحيحة، ولكن خاصية NSSTRING * اسم "غير صالح".


#import "Simple_TableViewController.h"
@implementation Simple_TableViewController

- (void)viewDidLoad {       
    NSMutableArray *array = [[NSMutableArray alloc] init];
    Database *database = [Database instance];

    array = [database getAllCars];
    [self setListData:array];
    [array release];
}
- (NSMutableArray *)listData {
    return listData;
}
- (void)setListData:(NSMutableArray *)newListData {
    if (listData != newListData) {
        [listData release];
        listData = [newListData mutableCopy];
    }
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
- (void)dealloc {
    [listData release];
    [super dealloc];
}
- (NSInteger)tableView:(UITableView *)tableView
 numberOfRowsInSection:(NSInteger)section
{
    return [listData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
            cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero
                                                 reuseIdentifier:SimpleTableIdentifier] autorelease];
    }

    NSUInteger row = [indexPath row];
    Car *car = [listData objectAtIndex:row];

    cell.text = car.name;
    cell.font = [UIFont boldSystemFontOfSize:17];

    return cell;
}
- (NSInteger)tableView:(UITableView *)tableView
indentationLevelForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 0;
}
- (NSIndexPath *)tableView:(UITableView *)tableView
  willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger row = [indexPath row];
    if (row == 0) {
        return nil;
    }

    return indexPath;
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];

    NSString *message = [[NSString alloc] initWithFormat:@"You selected %@", [[listData objectAtIndex:row] name]];
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Row Selected!"
                                                                    message:message
                                                                  delegate:nil
                                                      cancelButtonTitle:@"Yes I Did"
                                                      otherButtonTitles:nil];
    [alert show];

    [message release];
    [alert release];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 35;
}

@end

لقد عدلت مع غيبوبة هذا والاحتفاظ بذلك حتى سقط أصابعي. لقد قمت بعمل بعيدا مع reperty (غير مراقب، الاحتفاظ بالاحتفاظ) و Synthesize متغير ListData، ولا يزال لدي نفس المشكلة.

شكرا مقدما على أي نصيحة يجب أن تقدمها!

هل كانت مفيدة؟

المحلول

في INTWithPrimaryKey: ETC: الطريقة، تحتاج إلى الاحتفاظ بتلك القيم، أو استخدام تدوين النقاط لتعيينها (على افتراض أنها خصائص معلنة مع الكلمة الرئيسية الاحتفاظ). جرب هذا:

- (id)initWithPrimaryKey:(NSInteger)pk categoryId:(NSNumber *)catId carName:(NSString *)n {
    if (self = [super init]) {
        primaryKey = pk;
        categoryId =[catId retain];
        name = [n retain];
    }

return self;

}

أيضا، وهذا مجرد مشكلة أسلوب، قد تفكر بعض الشيء المزيد من أسماء السفلات من 'n' و 'pk'. مستقبلك سوف الذات شكرا لك.

نصائح أخرى

قليلا خارج الموضوع - بن لديه الإجابة التي تبحث عنها ولكن المنطق في بعض الكود الخاص بك هو قليل من التعرض.

- (void)setName:(NSString *)aString {
    if ((!name && !aString) || (name && aString && [name isEqualToString:aString])) return;
    [name release];
    name = [aString copy];
}

أنت لا تحتاج حقا للتحقق (!name && !aString) إنها ممارسة آمنة ومشتركة لإعادة تعيين Nil فوق Nil وإرسال رسالة إصدار (أو أي رسالة) إلى NIL. الدوائر القصيرة وقت التشغيل هذا الأخير وسيقوم Optimiser بإزالة السابق. إذا كان إعداد اسم NIL هو خطأ، فيجب عليك تأكيد أن الفضل ليس لا شيء لا شيء

وبالمثل، تكون NSStrings جيدة جدا. لا تهتم بتحسين القضية حيث تقوم بتحديد اسم السيارة إلى الاسم الذي تم تعيينه بالفعل. infact، الشيك الخاص بك [name isEqualToString:aString] الذي تستغرقه في كل مرة يقوم فيها بشخص ما بوضع سلسلة غير مذكرة غير أبطأ من الإصدار والنسخ الذي تتجنب فيه في أقلية الحالات.

إذا قمت بالتحقق من ما يحدث عند إرسال نسخة إلى nsstring، فستجد أنه يزيد فقط من عدد الاحتفاظ بالاحتفاظ. لاحظ أن هذا غير صحيح بالنسبة ل NSMutablestring لأسباب واضحة ؛-)

قاعدة جيدة من الإبهام - تحسين عندما يكون لديك جميع الوظائف وتحسين ما هو بطيئ (أو كبير).

أخيرا، متابعة تعليقات Ben حول التسمية، كنت أعيد تسميت جدوء إلى Acarname أو شيء آخر مزيد من الوصف - مرة أخرى، ستفضل نفسك مستقبلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top