Ios 在MRC中阻塞为什么此代码不会崩溃

Ios 在MRC中阻塞为什么此代码不会崩溃,ios,objective-c,Ios,Objective C,档案员.h @interface Person:NSObject + (void)callBlock:(void (^)())block; @end 档案员 @imp: + (void)callBlock:(void (^)())block { [NSThread sleepForTimeInterval:2]; block(); } @end ViewDidLoad中的代码: Person *p = [[Person alloc] init]; void (^block)()

档案员.h

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

@imp:
+ (void)callBlock:(void (^)())block
{ 
   [NSThread sleepForTimeInterval:2];
   block();
}
@end
ViewDidLoad中的代码:

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

结束

我的问题:

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

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

  • 我想我的代码和下面的一样

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


    对不起!两个程序都使用mrc!!!我写得不清楚

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

    正如注释中指出的,第一个示例没有崩溃,因为块是在函数范围中定义的,直到调用块之后才结束


    另一方面,第二个示例在次函数中定义了块,次函数在调用块之前结束。因此,在块调用时,堆栈已被修改,块已无效。

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

    因此,有一种解释:

    个人对象案例

  • 您可以创建对象
  • 创建块
  • 你叫街区
  • 块将对象注销
  • 块释放对象 这就是为什么没有撞车
  • 字符日志大小写

    由于您没有使用ARC,因此它是这样的:

  • 添加记录char的块
  • 离开将块添加到数组的函数后,刚创建的字符将从内存中释放。 如果您使用ARC进行内存管理,它将使该字符在内存中保持活动状态,直到该块存在。但一旦您从数组中移除它并且块的引用计数等于0,这个字符也会被释放
  • 从数组中获取一个块
  • 调用它,它引用已经释放的char的内存地址,崩溃出现。正如您的错误中所解释的: 执行错误访问(代码=1,地址=0x0) 意味着,您指向零地址(换句话说,空指针异常)

  • 就是这样。

    为什么您认为该块会被释放?如果该代码在viewcontroller中,在viewdidload中,它会崩溃吗?我试试这个!stackblock函数在调用后不可用?是的,但函数在调用块后才超出作用域。@trojanfoe试图说的是所有调用都是同步的,因此函数在block()返回后才在作用域内。第二组代码将崩溃,除非一组(不)幸运。我在viewcontroller中运行此代码。它打印“Bn”<代码>@implementation ViewController-(void)viewDidLoad{[super viewDidLoad];example();}void example_addBlockToArray(NSMutableArray*array){char b='b';[array addObject:^{printf(“%cn”,b);}];}void example(){NSMutableArray*array=[NSMutableArray];example_addBlockToArray(array);void(^block)(=[array objectAtIndex:0];block();}@end因此呢?正如我所说的,如果你运气不好,它不会崩溃。不能保证在调用块之前堆栈会被修改,但假设它不会被修改,这是一个可怕的错误。因此,为什么它没有崩溃对你来说是不幸运的。好吧,我是iOS新手,不太理解你的问题。我认为问题是pe变量为什么您认为ARC没有被使用?@Avi“为什么您认为ARC没有被使用?”因为
    [p release];
    ;)我认为ARC没有被使用,因为在作者的示例中,在对象上使用了release消息。它在没有弧的情况下会崩溃,在弧的情况下效果很好。第二个例子没有任何MMM,正如预期的那样,它在ARC下崩溃。ARC vs MMM与解释无关。@Avi老实说,Alex与实际发生的情况非常接近:当块被释放时,它也会释放所有已复制到堆中的导入变量。
     void example_addBlockToArray(NSMutableArray *array) {
       char b = 'B';
       [array addObject:^{
          printf("%cn", b);
       }];
     }
    
     void example() {
          NSMutableArray *array = [NSMutableArray array];
          example_addBlockToArray(array);
          void (^block)() = [array objectAtIndex:0];
          block();
        }