dealloc下的通知 ios_ios 在dealloc 移除通知, 还能收到通知, 报错 - CSDN
  • iOS dealloc方法没有调用

    今天coding的时候写了一个dealloc方法打了一个断点,building……运行……点击进入页面……返回。、。、???竟然没有调用dealloc方法???这是肿么回事?

    仔细查看了下代码、把代码注释掉运行,竟然好了。

    原来是用Notificationcenter(通知中心)写的block方法使页面返回的时候没有销毁:

    [[NSNotificationCenter defaultCenter]addObserverForName:UIKeyboardDidChangeFrameNotification object:self queue:nil usingBlock:^(NSNotification *note) {

        <#code#>

    }];

    把上面的改成这种使用方法就好了:

    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(searchBarCancelButtonShow) name:UIKeyboardDidChangeFrameNotification object:nil];


    同理所有没有调用dealloc方法的页面都是用了常驻内存的对象。大笑

    展开全文
  • 最近项目突然被说会闪退,且无法重现,时有出现。接到问题后一步步排查,终于发现问题。 表现:某个页面的通知观察者方法被多次调用!...3、一般我们会在dealloc方法里面移除通知,打断点发现,dealloc方法

    最近项目突然被说会闪退,且无法重现,时有出现。接到问题后一步步排查,终于发现问题。

    表现某个页面的通知观察者方法被多次调用!

    原因查找:

    1、通知的监听这里我写在viewDidLoad里面,多次被调用只能说明多次发送了通知,或者多次添加了观察者。

    2、通知的发送确定没多次调用,而通知的监听为何会被多次添加?

    3、一般我们会在dealloc方法里面移除通知,打断点发现,dealloc方法并未调用

    4、通知每进一次页面添加一次,pop之后又未被移除,那就可能造成内存泄露,闪退!

    解决思路也就是要确定dealloc方法为何不走!

    dealloc不被调用的原因:

    1、ViewController中存在定时器NSTimer,定时器一跑起来就增加了ViewController的return count,如果你不将这个timer invalidate,则控制器无法释放;

    2、ViewController中有强引用代理(delegate),改为weak修饰;

    3、ViewController中有Block,且有循环引用。这个也是我不能调用dealloc的真正原因。Block体内使用实例变量会造成循环引用,使得拥有这个实例的对象不能释放。 
    例如你这个类叫OneViewController,有个属性是NSString *name; block的持有者也是VC的一个属性,如果你在block体中使用了self.name,那样子的话这个类就没法释放。

    注意:VC持有的实例变量和@implementation下面创建的全局变量也会被循环引用

    @interface GroupChpPay ()
    {
        UIView *_xxView;
    }
    @implementation GroupChpPay
    {
        UIView *_xxView;
    }

    即使在你的block代码中没有显式地出现"self",也会出现循环引用!就像上面的实例变量和全局变量,并不会使用self.调用,其实也会被循环引用。只要你在block里用到了self所拥有的东西!

    但对于这种情况,我们无法通过加__weak声明或者__block声明去禁止block对self进行强引用或者强制增加引用计数。但我们可以通过指针来避免循环引用,具体是这么做的:

    __weak typeof(self) weakSelf = self;
    self.blkA = ^{
        __strong typeof(weakSelf) strongSelf = weakSelf;//加一下强引用,避免weakSelf被释放掉
        NSLog(@"%@", strongSelf->_xxView); //不会导致循环引用.
    };


    排查方法:

    1、在添加通知的页面搜索所有 ^ 符号,也就是排查所有block方法有没有使用弱引用。基本都改好之后,dealloc方法可以被调用了,控制器销毁通知成功移除,问题解决!

    2、真找不到哪里出错,最笨的方法,将可能出错的代码一段段注释排查!

    还有值得一提的是,一般编译器会对需要使用weak弱引用的地方给出警告,但我这里没有警告,是在环信的SDK写的类里面,坑。

    展开全文
  • 在MRC时代,我们需要在 dealloc中做很多,比如释放对象,等等; 如今我们已经进入ARC时代,对于普通对象的释放,系统已经帮我们做好了; 那是否可以高枕无忧了呢?在ARC我们应该做什么? 观点: ARC,系统可以帮我们...

    在MRC时代,我们需要在 dealloc中做很多,比如释放对象,等等;

    如今我们已经进入ARC时代,对于普通对象的释放,系统已经帮我们做好了;

    那是否可以高枕无忧了呢?在ARC下我们应该做什么?


    观点:

    ARC下,系统可以帮我们释放该对象,及其包含的对象;

    但是却无法释放不属于该对象的一些东西,如:


    1.通知的观察者,或KVO的观察者


    由于通知中心是系统的一个单例,你在注册通知的观察者时,实际上是在通知中心注册的,

    这时,即使ARC下系统帮我们释放了对象,但是在通知中心的观察还是没有移除,那么当有

    该通知时,依然会尝试调用该对象的接受通知的方法,这可能会导致一些问题.

    这一点有点像,你晚上六点下班了...但是却没有刷卡...,


    2.对象强委托/引用的解除(例如XMPPMannerger的delegateQueue)


    对于其他的对象来把你当做委托 delegate时,并且是 强引用时,即时你自身被释放,但是引用你的对象依然还在,

    这时需要在引用你的对象移除该delegate


    3.做一些其他的注销之类的操作(关闭程序运行期间没有关闭的资源)


    一个对象,如一个ViewController在销毁之前有可能需要和server打交道;

    这时我们也可以在dealloc中写


    关于dealloc的底层实现,可以参照objc运行时代码


    示例,ARC下我们应该做的:

    [html] view plain copy
     print?
    1. - (void)dealloc  
    2. {  
    3.     [[NSNotificationCenter defaultCenter] removeObserver:self];//移除通知观察者  
    4.     [[XMPPManager sharedManager] removeFromDelegateQueue:self];//移除委托引用  
    5.   [ [MyClass shareInstance]  doSomething ]//其他操作  
    6.      
    7. }  


    ARC下我们没必要做的


    [html] view plain copy
     print?
    1. - (void)dealloc  
    2. {  
    3.     _name = nil;  
    4.    [_time invalid];  
    5. }  


    [html] view plain copy
     print?
    1. 总结: dealloc在ARC下的作用就是释放 系统无法释放的该对象占用的资源,或者其他对象对该对象的引用.  


    原文出自:http://blog.csdn.net/yangbingbinga/




    展开全文
  • 众所周知,iOS开发的时候,使用ARC的话,dealloc函数是不需要实现的,写了反而会出错。 有些特殊的情况,dealloc函数还是需要的。比如,在画面关闭的时候,需要把ViewController的某些资源释放,在viewDidDissppear...

    众所周知,iOS开发的时候,使用ARC的话,dealloc函数是不需要实现的,写了反而会出错。
    有些特殊的情况,dealloc函数还是需要的。比如,在画面关闭的时候,需要把ViewController的某些资源释放,在viewDidDissppear不一定合适,viewDidUnload一般情况下只在memory warning的时候才被调用。
    MRC的情况下,我们自然会想到dealloc函数。

    使用情况

    其实ARC环境下,也没有把dealloc函数禁掉,还是可以使用的。但不用手动调用[supper dealloc]了,因为系统在此方法返回的时候自动执行[supper dealloc]。
    在dealloc重写方法中,你可以释放一些不在 ARC 控制下的资源。 例如 Core Foundation 对象中调用 CFRelease(), 对那些通过 malloc() 分配的内存调用 free(), 注销通知,注销观察者,停止 Timer 等。

    例子

    画面上有UIWebView,它的delegate是该画面的ViewController,在WebView载入完成后,需要做某些事情,比如,把indicator停掉之类的。
    如果在WebView载入完成之前关闭画面的话,画面关闭后,ViewController也释放了。但由于WebView正在载入页面,而不会马上被释放,等到页面载入完毕后,回调delegate(ViewController)中的方法,由于此时ViewController已经被释放,所以会出错:message sent to deallocated instance

    解决方案

    解决办法是在dealloc中把WebView的delegate释放。

    -(void)dealloc 
    {
        self.webView.delegate = nil;
    }
    

    总结

    ARC 下, 不用手动调用[supper dealloc]了,因为系统在此方法返回的时候自动执行[supper dealloc]。在dealloc重写方法中,你可以释放一些不在 ARC 控制下的资源。 例如 Core Foundation 对象中调用 CFRelease(), 对那些通过 malloc() 分配的内存调用 free(), 注销通知,注销观察者, 请求取消等。

    延伸阅读 #重要#:
    ARC下dealloc过程及.cxx_destruct的探究

    相关阅读:
    ARC下的注意事项

    展开全文
  • ios的viewcontroller生命周期是 init -> loadView -> viewDidLoad -> viewWillAppear -> viewDidAppear -> viewWillDisappear -> viewDidAppear -> viewDidUnload -> dealloc 当我们使用NSNotificationCenter方法,...

    ios的viewcontroller生命周期是 init -> loadView -> viewDidLoad -> viewWillAppear -> viewDidAppear -> viewWillDisappear -> viewDidAppear -> viewDidUnload -> dealloc

    当我们使用NSNotificationCenter方法,可以在viewDidLoad中添加监听,在dealloc中remove监听,但是有的时候我们发现,在退出这个vc的时候,系统不调用dealloc方法,造成这样的方法可能有以下几种原因(目前知道的):


    1、viewcontroller中存在定时器NSTimer

      [self.timer invalidate];//结束定时

      self.timer = nil;//nil


    2、viewcontroller中有代理Delegate,需要设置delegate的时候,设置为weak

    @property (nonatomic,weak) id<WorkHistoryDelegate>delegate;


    3、viewcontroller中有Block方法

    block会把它里面的所有对象强引用,包括当前控制器self,因此有可能会出现循环引用的问题。比如viewController中有个block属性,在block中又强引用了self或者其他成员变量,那么这个viewController与自己的block属性就形成循环引用,导致viewController无法释放。

        __weak typeof(self) weakSelf = self;

        [self.tableView tableViewAddUpLoadRefreshing:^{

    [weakSelf loadCommentListData];

        }];




    展开全文
  • iOS NSNotification 通知机制
  • 我昨天发现我的导航控制器在pop的时候居然没有走dealloc方法,我在leaks里面去运行,也没有发现内存泄漏的提示。但是作为一个合格的程序员一定不能允许出现这种情况。所以我开始 一步一步的查询。 归根结底,是...
  • 为什么 iOS 9 之前需要手动移除观察者对象? 观察者注册时,通知中心并不会对观察者对象做 retain 操作,而是对观察者对象进行unsafe_unretained 引用。 什么是unsafe_unretained?因为 Cocoa 和 Cocoa Touch 中的...
  • 比如通知的移除、baiduSDK中的变量置nil等都需要重写dealloc方法来实现。注意,ARC工程是可以重写dealloc方法并被系统调用的,但不需要手动调用父类的dealloc,手写[super dealloc]方法会报错,事实上系统会自动帮你...
  • IOS-ARC下dealloc的作用

    2015-04-25 11:09:30
    但一些不在ARC控制的资源,侧需要在dealloc方法里作处理,如: Core Foundation 对象中调用 CFRelease(), 对那些通过 malloc() 分配的内存调用 free(), 注销通知,停止timer, 等等 。
  • 之前很少用block和delegate,由于页面比较复杂,通常都用通知,这样也可以降低模块之间的耦合性,最近新换了一家公司,其中有一个人脸识别的功能,一直调用图片输出代理方法,导致好用了大量cpu,导致设备发热,交接...
  • 今天无意中又捯饬了观察者模式,发现之前项目中的通知没有进行移除,可是控制器销毁后竟然没有崩溃,查了资料也没有找到很直观的解释(也可能关键字搜索问题),就查了API,有综合了网上看到的各种博客文章,只是...
  • 在MRC时代,我们需要在 dealloc中做很多,比如释放对象,等等; 如今我们已经进入ARC时代,对于普通对象的释放,系统已经帮我们做好了; 那是否可以高枕无忧了呢?在ARC我们应该做什么? 观点: ARC,...
  • 在开发中weak关键字使用的比较多,一般开发人员都知道,使用weak可以防止循环引用。但是防止循环引用之前是使用unsafe_unretained关键字unsafe_unretained
  • MRC下dealloc 方法其实在MRC中dealloc方法存在的主要意义是为了 释放自身的实例变量, 移除观察者, 停止timer, 移除通知, 代理置空等。 注意MRC dealoc 方法一定要在最后写 [super dealloc]; ARC 系统会帮助...
  •  在dealloc方法中移除通知观察者带来crash  NSNotificationCenter中的通知消息已经发出,而观察者对象子线程释放,也就是抛送通知消息的线程和观察者对象子线程释放的线程不一致时,存在crash风险,原因是...
  • dealloc: ARC唯一一个留着 dealloc 方法的原因就是, 你需要释放一些不在 ARC 控制的资源。 例如 Core Foundation ...对象中调用 CFRelease(), ...iOS中viewController被POP后不调用dealloc的问题
  • 在 ARC 环境,重载的 dealloc 方法一样会被调用,只不过,不能在该方法的实现中调用父类的该方法。 下面看个示例来验证一下: 一个待测试的类 Test,创建和销毁它,在 ARC 环境看看 dealloc 是否被调用了...
  • 在了解控制器的生命周期之后,我们都...很多时候我们根据自身需要将相关代码逻辑添加到这两个方法中,我们看如下代码片段: 监听键盘的通知代码 这段代码是在控制器的viewDidLoad:方法中注册了一个键盘弹出的
1 2 3 4 5 ... 20
收藏数 7,734
精华内容 3,093
关键字:

dealloc下的通知 ios