22day 遇到的问题 \内存管理

来源:互联网 发布:三十后换工作 知乎 编辑:程序博客网 时间:2024/05/29 00:30

前言:

需要释放的资源:imageCache、queue、operations、view、通知监听者的移除。销毁soundID
释放的方法:dealloc 、applicationDidReceiveMemoryWarning、didReceiveMemoryWarning

内存管理

凡是函数名中带有create、copy、new、retain等字眼的,都应该在不需要这个数据的时候进行release。

   GCD的数据类型在ARC环境下不需要进行release;[而CF的数据类型在ARC、MRC环境下都需要做release的](http://blog.csdn.net/z929118967/article/details/74332012) 
/* 内存管理的补充:     1、foundation框架 OC语言     2、core foundation 框架     1)、C语言,例如通讯录就是基于这个框架。     2)、core foundation 框架 在ARC、非ARC编译环境下都要管理内存对象。即core foundation 框架中手动创建的数据类型,都需要手动释放     foundation 和 core foundation 的数据类型可以相互转换     */    NSString *str = @"123";    CFStringRef  str2 = CFBridgingRetain(str);//Casts an Objective-C pointer to a Core Foundation pointer and also transfers ownership to the caller.    CFStringRef  str3 = (__bridge CFStringRef)(str);//桥接,跨框架的数据类型转换    NSString *str4 = CFBridgingRelease(str3);//Moves a non-Objective-C pointer to Objective-C and also transfers ownership to ARC.    NSString *str5 = (__bridge NSString *)(str3);//不改变拥有者    NSLog(@"%@,%@,%@,%@,%@",str,str2,str3,str4,str5);    //释放core foundation数据类型//    CFArrayRef array = CFArrayCreate(NULL, NULL, 10, NULL);//    CFRelease(array);

ps: 桥接

2、 dealloc

移除通知中心的Observer
停止网络监控Notifier //关闭网络检测

- (void)dealloc{[self.netReachability stopNotifier];  [[NSNotificationCenter defaultCenter] removeObserver:self name:kReachabilityChangedNotification object:nil];}

ASI框架的安全内存回收建议

// Clears all delegates and blocks, then cancels the request- (void)clearDelegatesAndCancel;//request并没有retain你的delegate,所以在没有请求完的时候释放了此delegate,需要在dealloc方法里先取消所有请求,再释放请求实例

可以调用ASIHTTPRequest 对象的dealloc方法

3、开启僵尸对象(Zombie Objects)来定位内存问题

4、didReceiveMemoryWarning

-(void)didReceiveMemoryWarning    {            [super didReceiveMemoryWarning];//即使没有显示在window上,也不会自动的将self.view释放。            // Dispose of any resources that can be recreated.            // 此处做兼容处理需要加上ios6.0的宏开关,保证是在6.0下使用的,6.0以前屏蔽以下代码,否则会在下面使用self.view时自动加载viewDidUnLoad            if ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0) {             //需要注意的是self.isViewLoaded是必不可少的,其他方式访问视图会导致它加载 ,在WWDC视频也忽视这一点。             if (self.isViewLoaded && !self.view.window)// 是否是正在使用的视图             {                   //code                   self.view = nil;// 目的是再次进入时能够重新加载调用viewDidLoad函数。             }           }    }
/**内存处理*/- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    [self.images removeAllObjects];    [self.operations removeAllObjects];    [self.queue cancelAllOperations];}

/* 销毁soundID/
通过AudioServicesDisposeSystemSoundID 销毁soundID。并从字典数组移除。

- (void)didReceiveMemoryWarning{    [DKAudioTool audioServicesDisposeWithFileName:@"buyao.wav"];//音频的销毁}

5.applicationDidReceiveMemoryWarning

/**内存管理*/@implementation AppDelegate- (void) applicationDidReceiveMemoryWarning:(UIApplication *)application{    SDWebImageManager *imageMgr = [SDWebImageManager sharedManager];    [imageMgr cancelAll];    [imageMgr.imageCache clearMemory];}

小结

需要释放的资源:imageCache、queue、operations、view、通知监听者的移除。销毁soundID。
释放的方法:dealloc 、applicationDidReceiveMemoryWarning、didReceiveMemoryWarning

遇到的问题

一、加载图片的问题
1、App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app’s Info.plist file.
https://developer.apple.com/library/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS9.html#//apple_ref/doc/uid/TP40016198-DontLinkElementID_13
在info.plist中添加

解决在iOS9 beta1中,苹果将原http协议改成了https协议,使用 TLS1.2 SSL加密请求数据。

<key>NSAppTransportSecurity</key>    <dict><key>NSAllowsArbitraryLoads</key><true/>    </dict>

二、加载XIB问题
1、xib文件上的对象顺序问题

ps: xib 最好只放一个对象

代码

- (IBAction)tapToolBar:(UITapGestureRecognizer *)sender {    NSLog(@"%s",__func__);}+ (instancetype)toolBar{    return [[[NSBundle mainBundle]loadNibNamed:@"HLtoolBar" owner:nil options:nil]firstObject];}

1.问题分析:

 [UITapGestureRecognizer superview]: unrecognized selector sent to instance 0x7a20fa60
 1)superview 方法属于UIView 2)HLtoolBar *toolBar =[HLtoolBar toolBar]; ->3)    [self.view addSubview:toolBar];

po toolBar 即可看出问题所在。

 po toolBar <UITapGestureRecognizer: 0x79695ef0; state = Possible; view = <HLtoolBar 0x796962b0>; target= <(action=tapToolBar:, target=<HLtoolBar 0x796962b0>)>>

结论:错误是:将UITapGestureRecognizer 当作UIView使用

回到加载xib类方法进行分析:

 return [[[NSBundle mainBundle]loadNibNamed:@"HLtoolBar" owner:nil options:nil]lastObject];

使用 po 即可看出: lastObject 是UITapGestureRecognizer
firstObject 才是HLtoolBar

 po [[NSBundle mainBundle]loadNibNamed:@"HLtoolBar" owner:nil options:nil] <__NSArrayM 0x7bfd4a20>( <HLtoolBar: 0x7bfd5570; frame = (0 0; 200 100); autoresize = W+H; gestureRecognizers = <NSArray: 0x7bfd9810>; layer = <CALayer: 0x7bfd4a70>>, <UITapGestureRecognizer: 0x7bfd51b0; state = Possible; view = <HLtoolBar 0x7bfd5570>; target= <(action=tapToolBar:, target=<HLtoolBar 0x7bfd5570>)>> )

2、VC的View的使用xib定义 的时候,注意事项
File‘s owner 修改为对应的VC,并设置VC的View的连线
p s: 注意View的xib的文件名称,是否与其它的VC名称一样

[[HLViewController alloc]init];执行过程分析:

(1):去掉Controlle之后,同名的xib--HLView.xib 2)找完全同名的xib--HLViewController.xib 

问题:-Cast of an indirect pointer to an Objective-C pointer to ‘CFTypeRef ’ (aka ‘const void *‘) is disallowed with ARC
————————————————————————

知识补充

ARC的简介

开启僵尸对象调试模式

block本身是像对象一样可以retain,和release

 1)block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上。 他本身的作于域是属于创建时候的作用域,一旦在创建时候的作用域外面调用block将导致程序崩溃 2)解决这个问题的方法就是在创建完block的时候需要调用copy的方法。copy会把block从栈上移动到堆上,那么就可以在其他地方使用这个block

宏的定义语法

参数拼接:
参数:classname

#define HSSingletonH(classname) +(instancetype)share##classname

//定义weakself,方便在block中使用self
参数:weakSelf

#define WS(weakSelf) __weak __typeof(&*self)weakSelf = self;
原创粉丝点击