free 与 CFRelease 的区别

如果我们使用 creat new copy 等函数,就会开辟一段堆空间,返回一个对象。

用一个指针指向这个对象:ptr = obj;,我们要释放这块对象的内存,就可以这样做:free(ptr); ,这时在堆上的内存就已经被释放了。但这还没有完,虽然我们堆上的空间已经被释放了,但是ptr里面还是有值的,如果仍然在程序中使用ptr指针的话就会出现坏内存访问的问题。正确的做法是在free之后,再清空指针:ptr = NULL;

如果上述步骤先执行的是ptr = NULL,那么堆上的这块内存将永远不会被释放!


在 OC 中创建的 CF 对象,内存是不被 ARC 所管理的。假设有一个 CF 对象 cfObj 和指针 cfPtr: cfPtr = cfObj;

当 cfObj 创建的时候会占用堆上的一块内存,记为堆空间1

cfObj 本质上是一个结构体,它里面可能有其它的指针,它们都有可能会创建新的堆空间记为堆空间2~N

如果调用 free(cfPtr),那么仅仅只会释放堆空间1的内存,堆空间2~N将永远不会被释放。

如果使用 CFRelease(cfPtr),它会先释放堆空间2~N,再释放堆空间1。它们都会得到释放。


还有一个问题

上面提到了使用 free 之后要将指针置为 NULL 才能将指针清空。
那么使用 CFRelease 之后,要不要置为 NULL?
我在测试的时候发现,如果只是 CFRelease(cfPtr) 的话,释放之后 cfPtr 里面存储的还是之前的地址,如果在执行 cfPtr = NULL 的话,cfPtr 的值才会变成 0x0000000000000000。也就是说 CFRelease 也需要置 NULL 才能清空指针。

那为什么平时看别人写的代码中似乎没有这样的操作?我觉得是当程序执行完函数后 cfPtr 在栈上的空间会被销毁,一般不会造成问题。

以上是个人的看法,如果有误的话请指出来!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以设置lable的字体-(void)setText:(NSString *)text WithFont:(UIFont *)font AndColor:(UIColor *)color{ self.text = text; int len = [text length]; NSMutableAttributedString *mutaString = [[NSMutableAttributedString alloc]initWithString:text]; [mutaString addAttribute:(NSString *)(kCTForegroundColorAttributeName) value:(id)color.CGColor range:NSMakeRange(0, len)]; CTFontRef ctFont2 = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize,NULL); [mutaString addAttribute:(NSString *)(kCTFontAttributeName) value:(__bridge id)ctFont2 range:NSMakeRange(0, len)]; CFRelease(ctFont2); resultAttributedString = mutaString; } -(void)setKeyWordTextArray:(NSArray *)keyWordArray WithFont:(UIFont *)font AndColor:(UIColor *)keyWordColor{ NSMutableArray *rangeArray = [[NSMutableArray alloc]init]; for (int i = 0; i < [keyWordArray count]; i++) { NSString *keyString = [keyWordArray objectAtIndex:i]; NSRange range = [self.text rangeOfString:keyString]; NSValue *value = [NSValue valueWithRange:range]; if (range.length > 0) { [rangeArray addObject:value]; } } for (NSValue *value in rangeArray) { NSRange keyRange = [value rangeValue]; [resultAttributedString addAttribute:(NSString *)(kCTForegroundColorAttributeName) value:(id)keyWordColor.CGColor range:keyRange]; CTFontRef ctFont1 = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize,NULL); [resultAttributedString addAttribute:(NSString *)(kCTFontAttributeName) value:(__bridge id)ctFont1 range:keyRange]; CFRelease(ctFont1); } }
- (void)close { // Empty queues. [self emptyQueues]; [partialReadBuffer release]; partialReadBuffer = nil; [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(disconnect) object:nil]; // Close streams. if (theReadStream != NULL) { CFReadStreamSetClient(theReadStream, kCFStreamEventNone, NULL, NULL); CFReadStreamUnscheduleFromRunLoop (theReadStream, theRunLoop, kCFRunLoopDefaultMode); CFReadStreamClose (theReadStream); CFRelease (theReadStream); theReadStream = NULL; } if (theWriteStream != NULL) { CFWriteStreamSetClient(theWriteStream, kCFStreamEventNone, NULL, NULL); CFWriteStreamUnscheduleFromRunLoop (theWriteStream, theRunLoop, kCFRunLoopDefaultMode); CFWriteStreamClose (theWriteStream); CFRelease (theWriteStream); theWriteStream = NULL; } // Close sockets. if (theSocket != NULL) { CFSocketInvalidate (theSocket); CFRelease (theSocket); theSocket = NULL; } if (theSocket6 != NULL) { CFSocketInvalidate (theSocket6); CFRelease (theSocket6); theSocket6 = NULL; } if (theSource != NULL) { CFRunLoopRemoveSource (theRunLoop, theSource, kCFRunLoopDefaultMode); CFRelease (theSource); theSource = NULL; } if (theSource6 != NULL) { CFRunLoopRemoveSource (theRunLoop, theSource6, kCFRunLoopDefaultMode); CFRelease (theSource6); theSource6 = NULL; } theRunLoop = NULL; // If the client has passed the connect/accept method, then the connection has at least begun. // Notify delegate that it is now ending. if (theFlags & kDidPassConnectMethod) { // Delay notification to give him freedom to release without returning here and core-dumping. if ([theDelegate respondsToSelector: @selector(onSocketDidDisconnect:)]) { //[theDelegate performSelector:@selector(onSocketDidDisconnect:) withObject:self afterDelay:0]; [theDelegate onSocketDidDisconnect:self]; } } // Clear flags. theFlags = 0x00; }
最新发布
06-13

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值