使用ARC将消息发送到解除分配的实例

Ale*_*ere 2 debugging memory-management exc-bad-access objective-c

我通常不会问这样的问题,但我真的无法理解它.我有一个类'GetTableInfoFromDatabase',它连接到我的数据库并下载一些JSON.这在我的标签栏应用程序的第一个屏幕上运行得很好.我可以调用getNewData方法,因为我想要有效地刷新数据.

当我尝试创建'GetTableInfoFromDatabase'类的实例并从另一个选项卡调用相同的方法时,我的问题出现了.我收到以下错误:

*** -[GetTableInfoFromDatabase respondsToSelector:]: message sent to deallocated instance 0x1d89e830
Run Code Online (Sandbox Code Playgroud)

有趣的是,我正在使用ARC.罪魁祸首(在我看来)是ASIHTTPRequest.我必须启用-fno-objc-arc才能使项目进行编译.此库用于GetTableInfoFromDatabase类.

这是班级:

- (void) getEventDataWithSender:(id)sender{


ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"-------.com/getdata.php"]];
[request setDelegate:self];
NSLog(@"Running!");
[request startAsynchronous];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = appDelegate.managedObjectContext;
}
Run Code Online (Sandbox Code Playgroud)

这就是我所说的:

GetTableInfoFromDatabase *getInfo = [[GetTableInfoFromDatabase alloc]init];
[getInfo getEventDataWithSender:self];
Run Code Online (Sandbox Code Playgroud)

我甚至改变了标签的顺序,所以第一个要显示的标签只是调用这个方法,没有别的.甚至在'GetTableInfoFromDatabase'之前已经由最后一次初始化它的类初始化之前.仍然崩溃.

有没有人有任何想法?这太令人沮丧了!

jer*_*rts 10

如果计划将该变量公开给其他视图控制器,则需要将该变量分配给属性.在此代码执行后,ARC将,并且应该立即解除分配getInfo:

GetTableInfoFromDatabase *getInfo = [[GetTableInfoFromDatabase alloc]init];
[getInfo getEventDataWithSender:self];
Run Code Online (Sandbox Code Playgroud)

因此,如果此行包含在sayDidLoad:并且该方法中没有其他任何内容引用getInfo,则会立即释放该行.为什么,因为你没有告诉编译器它应该保留它.

因此,在暴露这个类的视图控制器中,在任何标签上它可能是...的孩子......你会做这样的事情:

ViewController.h

@class GetTableInfoFromDatabase;  // forward declaration

@interface ViewController : UIViewController

@property (strong, nonatomic) GetTableInfoFromDatabase *getInfo;
Run Code Online (Sandbox Code Playgroud)

ViewController.m

@implementation ViewController

@synthesize getInfo = _getInfo;

- (void) viewDidLoad {
    [super viewDidLoad];

    self.getInfo = [[GetTableInfoFromDatabase alloc]init]; // assign your value to a property

    [self.getInfo getEventDataWithSender:self];
}
Run Code Online (Sandbox Code Playgroud)

因此,当您在标题中将属性声明为" 强"时,它将保持对它的强引用.@Synthesize getInfo = _getInfo意味着它将为名为_getInfo的实例变量周围的self.getInfo创建一个getter和setter .如果你不想将它作为属性公开,只需要一个实例变量......你可以这样做:

ViewController.h

@class GetTableInfoFromDatabase;  // forward declaration

@interface ViewController : UIViewController {
    GetTableInfoFromDatabase _getInfo;
}
Run Code Online (Sandbox Code Playgroud)

ViewController.m

@implementation ViewController

- (void) viewDidLoad {
    [super viewDidLoad];

    _getInfo = [[GetTableInfoFromDatabase alloc]init]; // assign your value to a property

    [_getInfo getEventDataWithSender:self];
}
Run Code Online (Sandbox Code Playgroud)

默认情况下,除非另行指定,否则编译器将保持对该实例变量的强引用.您也可以使用弱引用,并且所有这些选项都有很好的文档记录.因此,对于ARC或普通的旧内存管理,如果希望它暂停一段时间,则需要创建实例变量或属性.

老实说......所有ARC为你做的是让你不必打电话给保留和释放.在ARC之前,设置该属性将如下所示:

    GetTableInfoFromDatabase getInfo = [[GetTableInfoFromDatabase alloc]init];

    self.getInfo = getInfo;

    [getInfo release];
Run Code Online (Sandbox Code Playgroud)

现在使用ARC,编译器只为您编写代码;)希望这有帮助!

    [self.getInfo getEventDataWithSender:self];
Run Code Online (Sandbox Code Playgroud)