在MRC中阻止为什么这段代码不会崩溃

时间:2015-11-04 11:22:22

标签: ios objective-c

File Person.h

const

File Person.m

@interface Person:NSObject
+ (void)callBlock:(void (^)())block;
@end

ViewDidLoad中的代码:

@imp:
+ (void)callBlock:(void (^)())block
{ 
   [NSThread sleepForTimeInterval:2];
   block();
}
@end

光洁度!

MyQuestion:

  1. 在main函数中,block var是一个堆栈块,这个块分配给函数+ callBlock:,而Person.m中的块也是一个堆栈块。它们的内容相同。

  2. 在我看来,在Person.m中调用之前,main中的块将被系统释放,所以我认为这个程序会崩溃,但它运行正常。为什么呢?

  3. 我认为我的代码与以下相同。

  4. ...

    Person *p = [[Person alloc] init];
    void (^block)() = ^{
    NSLog(@"%@",p);
      [p release];
    }
    [Person callBlock:block];
    

    这个程序崩溃了!它们之间有什么区别?

    抱歉!两个程序都使用mrc !!!我写得不清楚!

3 个答案:

答案 0 :(得分:2)

看起来,你正在使用手动内存管理。

因此是一个解释:

人物对象

  1. 您创建对象
  2. 您创建了块
  3. 你打电话给
  4. 阻止记录对象
  5. Block释放对象 这就是没有崩溃的原因
  6. 字符日志案例

    由于你没有使用ARC,它就是这样的:

    1. 您添加记录char的块
    2. 一旦离开将块添加到数组的函数,您刚创建的字符将从内存中释放。 如果您使用ARC进行内存管理,它将使此char保留在内存中,直到该块存在。但是一旦你从数组中删除它并且块的引用计数等于0,这个字符也会被释放。
    3. 你从数组中取出一个块
    4. 调用它,它引用已经释放的char的内存地址,出现崩溃。如您的错误中所述: EXC_BAD_ACCESS(代码= 1,地址= 0x0) 意味着,您指向零地址(换句话说,空指针异常)。
    5. 所以,就是这样。

答案 1 :(得分:1)

正如评论中指出的那样,第一个例子不会崩溃,因为块是在一个函数作用域中定义的,直到块被调用之后它才会结束。

另一方面,第二个例子定义了辅助函数中的块,该函数在调用块之前结束。因此,在块调用时,堆栈已被修改,块已变为无效。

答案 2 :(得分:0)

执行main函数后,main中的块将由系统释放,而不是在Person.m中调用之前。我在viewcontroller中尝试了第二个代码,它运行正常,而不是崩溃。