MRC转成ARC的三种方法

iOS项目MRC转ARC的两种方法 由于公司项目过于老旧,内存还是使用mrc进行管理,导致出现不少问题,最近着手将项目由mrc转换到arc上来,本人初步想法,有两种方案实施: 一、第一种方案(一步到位) 1、过滤无需转换的文件(需要统计出不需要转换的文件及第三方做标记) 不希望转换的文件,添加-fno-objc-arc标记; 对于第三方库如果有arc版的进行替换,没有的添加-fno-objc-arc标记; ... 阅读详情

回 到正题,我们讨论的是ARC,关于REST API和XML解析的技术细节就暂时先忽略吧..整个程序都是用MRC来进行内存管理的,首先来让我们把这个demo转成ARC吧。基本上转换为ARC意 味着把所有的retain,release和autorelease关键字去掉,在之前我们明确几件事情:
* Xcode提供了一个ARC自动转换工具,可以帮助你将源码转为ARC
* 当然你也可以自己动手完成ARC转换
* 同时你也可以指定对于某些你不想转换的代码禁用ARC,这对于很多庞大复杂的还没有转至ARC的第三方库帮助很大,因为不是你写的代码你想动手修改的话代码超级容易mess…

对于我们的demo,为了说明问题,这三种策略我们都将采用,注意这仅仅只是为了展示如何转换。实际操作中不需要这么麻烦,而且今后的绝大部分情况应该是从工程建立开始就是ARC的。


首先,ARC是LLVM3.0编译器的特性,而老的工程特别是Xcode3时代的工程的默认编译器很可能是GCC或者LLVM-GCC,因此第一步就是确认编译器是否正确。在Project设置面板,选择target,在Build Settings中将Compiler for C/C++/Objective-C选为Apple LLVM compiler 3.0或以上。为 了确保之后转换的顺利,在这里我个人建议最好把Treat Warnings as Errors和 Run Static Analyzer都打开,确保在改变编译器后代码依旧没有警告或者内存问题(虽然静态分析可能不太能保证这一点,但是聊胜于无)。好 了~clean(Shift+Cmd+K)以后Bulid一下试试看,经过修改后的demo工程没有任何警告和错误,这是很好的开始。(对于存在警告的代 码,这里是很好的修复的时机..请在转换前确保原来的代码没有内存问题)。


接下来就是完成从MRC到ARC的伟大转换了。还是在Build Settings页面,把Objective-C Automatic Reference Counting改成YES(如果找不到的话请看一看搜索栏前面的小标签是不是调成All了..这个选项在Basic里是不出现的),这样我们的工程就将 在所有源代码中启用ARC了。然后…试着编译一下看看,嗯..无数的错误。


这是很正常的,因为ARC里不允许出现retain,release之类的,而MRC 的代码这些是肯定会有的东西。我们可以手动一个一个对应地去修复这些错误,但是这很麻烦。Xcode为我们提供了一个自动转换工具,可以帮助重写源代码, 简单来说就是去掉多余的语句并且重写一些property关键字。





这个小工具是Edit->Refactor下的Convert to Objective-C ARC,点击后会让我们选择要转换哪几个文件,在这里为了说明除了自动转换外的方法,我们不全部转换,而只是选取其中几个转换 (MainViewController.m和AFHTTPRequestOperation.m不做转换)。注意到这个对话框上有个警告标志告诉我们 target已经是ARC了,这是由于之前我们在Build Settings里已经设置了启用ARC,其实直接在这里做转换后Xcode会自动帮我们开启ARC。点击检查后,Xcode告诉我们一个不幸的消息,不 能转换,需要修复ARC readiness issues..后面还告诉我们要看到所有的所谓的ARC readiness issues,可以到设置的General里把Continue building after errors勾上…What the f**k…好吧~先乖乖听从Xcode的建议”Cmd+,“然后Continue building after errors打勾然后再build。


问题依旧,不过在issue面板里应该可以看到所有出问题的代码了。在我们的例子里,问题出在SoundEffect.m里:

NSURL *fileURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil]; if (fileURL != nil) { SystemSoundID theSoundID; OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)fileURL, &theSoundID); if (error == kAudioServicesNoError) soundID = theSoundID; }
[html]  view plain copy
  1. NSURL *fileURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil]; if (fileURL != nil) { SystemSoundID theSoundID; OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)fileURL, &theSoundID); if (error == kAudioServicesNoError) soundID = theSoundID; }  
  2.   
  3. NSURL *fileURL = [[NSBundle mainBundle] URLForResource:filename withExtension:nil];  
  4. if (fileURL != nil)  
  5. {  
  6.     SystemSoundID theSoundID;  
  7.     OSStatus error = AudioServicesCreateSystemSoundID((CFURLRef)fileURL, &theSoundID);  
  8.     if (error == kAudioServicesNoError)  
  9.         soundID = theSoundID;  
  10. }  

这里代码尝试把一个NSURL指针强制转换为一个CFURLRef指针。这里涉及到一 些Core Services特别是Core Foundation(CF)的东西,AudioServicesCreateSystemSoundID()函数接受CFURLRef为参数,这是一个 CF的概念,但是我们在较高的抽象层级上所建立的是NSURL对象。在Cocoa框架中,有很多顶层对象对底层的抽象,而在使用中我们往往可以不加区别地对这两种对象进行同样的对待,这类对象即为可以”自由桥接”的对象(toll-free bridged)。NSURL和CFURLRef就是一对好基友好例子,在这里其实CFURLRef和NSURL是可以进行替换的。

通常来说为了代码在底层级上的正确,在iOS开发中对基于C的API的调用所传入的参 数一般都是CF对象,而Objective-C的API调用都是传入NSObject对象。因此在采用自由桥接来调用C API的时候就需要进行转换。但是在使用ARC编译的时候,因为内存管理的原因,编译器需要知道对这些桥接对象要实行什么样的操作。如果一个NSURL对 象替代了CFURLRef,那么在作用区域外,应该由谁来决定内存释放和对象销毁呢?为了解决这个问题,引入了bridge,bridge_transfer和__bridge_retained三个关键字。关于选取哪个关键字做转换,需要由实际的代码行为来决定。如果对于自由桥接机制感兴趣,大家可以自己找找的相关内容,比如适用类型、内部机制和一个简介~之后我也会对这个问题做进一步说明

回到demo,我们现在在上面的代码中加上__bridge进行转换。然后再运行 ARC转换工具,这时候检查应该没有其他问题了,那么让我们进行转换吧~当然在真正转换之前会有一个预览界面,在这里我们最好检查一下转换是不是都按照预 想进行了..要是出现大面积错误又没有备份或者出现各种意外的话就可以哭了…

前后变化的话比较简单,基本就是去掉不需要的代码和改变property的类型而已, 其实有信心的话不太需要每次都看,但是如果是第一次执行ARC转换的操作的话,我还是建议稍微看一下变化,这样能对ARC有个直观上的了解。检查一遍,应 该没什么问题了..需要注意的是main.m里关于autoreleasepool的变化以及所有dealloc调用里的[super dealloc]的删除,它们同样是MRC到ARC的主要变化..

好了~转换完成以后我们再build看看..应该会有一些警告。对于原来retain 的property,比较保险的做法是转为strong,在LLVM3.0中自动转换是这样做的,但是在3.1中property默认并不是 strong,这样在使用property赋值时存在警告,我们在property声明里加上strong就好了~然后就是 SVProgressHUD.m里可能存在问题,这是由于原作者把release的代码和其他代码写在一行了.导致自动转换时只删掉了部分,而留下了部分 不应该存在的代码,删掉对变量的空调用就好了..

自动转换之后的故事

然后再编译,没有任何错误和警告了,好棒~等等…我们刚才没有对 MainViewController和AFHTTPRequestOperation进行处理吧,那么这两个文件里应该还存在release之类的东西 吧..?看一看这两个文件,果然有各种release,但是为什么能编译通过呢?!明明刚才在自动转换前他们还有N多错的嘛…答案很简单,在自动转换的时 候因为我们没有勾选这两个文件,因此编译器在自动转换过后为这两个文件标记了”不使用ARC编译”。可以看到在target的Building Phases下,MainViewController.m和AFHTTPRequestOperation.m两个文件后面被加上了-fno- objc-arc的编译标记,被加上该标记的文件将不使用ARC规则进行编译。


提供这样的编译标记的原因是显而易见的,因为总是有一部分的第三方代码并没有转换为ARC(可能是由于维护者犯懒或者已经终止维护),所以对于这部分代码,为了迅速完成转换,最好是使用-fno-objc-arc标记来禁止在这些源码上使用ARC。

为了方便查找,再此列出一些在转换时可能出现的问题,当然在我们使用ARC时也需要注意避免代码中出现这些问题:

  • “Cast … requires a bridged cast”

这是我们在demo中遇到的问题,不再赘述

  • Receiver type ‘X’ for instance message is a forward declaration

这往往是引用的问题。ARC要求完整的前向引用,也就是说在MRC时代可能只需要在.h中申明@class就可以,但是在ARC中如果调用某个子类中未覆盖的父类中的方法的话,必须对父类.h引用,否则无法编译。

  • Switch case is in protected scope

现在switch语句必须加上{}了,ARC需要知道局部变量的作用域,加上{}后switch语法更加严格,否则遇到没有break的分支的话内存管理会出现问题。

  • A name is referenced outside the NSAutoreleasePool scope that it was declared in

这是由于写了自己的autoreleasepool,而在转换时在原来的pool中申明的变量在新的@autoreleasepool中作用域将被局限。解决方法是把变量申明拿到pool的申请之前。

  • ARC forbids Objective-C objects in structs or unions

可以说ARC所引入的最严格的限制是不能在C结构体中放OC对象了..因此类似下面这样的代码是不可用的

[html]  view plain copy
  1. typedef struct { UIImage *selectedImage; UIImage *disabledImage; } ButtonImages;  
  2. typedef struct {  
  3.     UIImage *selectedImage;  
  4.     UIImage *disabledImage;  
  5. } ButtonImages;  

这个问题只有乖乖想办法了..改变原来的结构什么的..

手动转换

刚才做了对demo的大部分转换,还剩下了MainViewController和 AFHTTPRequestOperation是MRC。但是由于使用了-fno-objc-arc,因此现在编译和运行都没有问题了。下面我们看看如何 手动把MainViewController转为ARC,这也有助于进一步理解ARC的规则。

首先,我们需要转变一下观念…对于MainViewController.h,在.h中申明了两个实例变量:

[html]  view plain copy
  1. @interface MainViewController : UIViewController { NSOperationQueue *queue; NSMutableString *currentStringValue; }  
  2.   
  3. @interface MainViewController : UIViewController    
  4. {  
  5.     NSOperationQueue *queue;  
  6.     NSMutableString *currentStringValue;  
  7. }  

我们不妨仔细考虑一下,为什么在interface里出现了实例变量的申明?通常来 说,实例变量只是在类的实例中被使用,而你所写的类的使用者并没有太多必要了解你的类中有哪些实例变量。而对于绝大部分的实例变量,应该都是 protected或者private的,对它们的操作只应该用setter和getter,而这正是property所要做的工作。可以说,将实例变量 写在头文件中是一种遗留的陋习。更好的写实例变量名字的地方应当与类实现关系更为密切,为了隐藏细节,我们应该考虑将它们写在 @implementation里。好消息是,在LLVM3.0中,不论是否开启ARC,编译器是支持将实例变量写到实现文件中的。甚至如果没有特殊需要 又用了property,我们都不应该写无意义的实例变量申明,因为在@synthesize中进行绑定时,我们就可以设置变量名字了,这样写的话可以让 代码更加简洁。

在这里我们对着两个实例变量不需要property(外部成员不应当能访问到它们),因此我们把申明移到.m里中。修改后的.h是这样的,十分简洁一看就懂~

[html]  view plain copy
  1. #import @interface MainViewController : UIViewController   
  2. @property (nonatomic, retain) IBOutlet UITableView *tableView;    
  3. @property (nonatomic, retain) IBOutlet UISearchBar *searchBar;   
  4. @end  
  5.   
  6.   
  7. #import  
  8. @interface MainViewController : UIViewController  
  9. @property (nonatomic, retain) IBOutlet UITableView *tableView;    
  10. @property (nonatomic, retain) IBOutlet UISearchBar *searchBar;   
  11. @end  
然后.m的开头变成这样:

[html]  view plain copy
  1. @implementation MainViewController { NSOperationQueue *queue;   
  2.  NSMutableString *currentStringValue;  }  
  3.   
  4. @implementation MainViewController  
  5. {  
  6.     NSOperationQueue *queue;   
  7.     NSMutableString *currentStringValue;   
  8. }  

这样的写法让代码相当灵活,而且不得不承认.m确实是这些实例变量的应该在的地 方…build一下,没问题..当然对于SoundEffect类也可以做相似的操作,这会让使用你的类的人很开心,因为.h越简单越好..P.S.另外 一个好处可以减少.h里的引用,减少编译时间(虽然不明显=。=)

然后就可以在MainViewController里启用ARC了,方法很简单,删掉 Build Phases里相关文件的-fno-objc-arc标记就可以了~然后..然后当然是一大堆错误啦。我们来手动一个个改吧,虽然谈不上乐趣,但是成功以 后也会很有成就~(如果你不幸在启用ARC后build还是成功了,恭喜你遇到了Xcode的bug,请Cmd+Q然后重新打开Xcode把=_=)

dealloc

红色最密集的地方是dealloc,因为每一行都是release。由于在这里 dealloc并没有做除了release和super dealloc之外的任何事情,因此简单地把整个方法删掉就好了。当然,在对象被销毁时,dealloc还是会被调用的,因此我们在需要对非ARC管理的 内存进行管理和必要的逻辑操作的时候,还是应该保留dealloc的,当然这涉及到CF以及以下层的东西:比如对于retain的CF对象要 CFRelease(),对于malloc()到堆上的东西要free()掉,对于添加的observer可以在这里remove,schedule的 timer在这里invalidate等等~[super dealloc]这个消息也不再需要发了,ARC会自动帮你搞定。

另外,在MRC时代一个常做的事情是在dealloc里把指向自己的delegate设成nil(否则就等着EXC_BAD_ACCESS吧 :P ),而现在一般delegate都是weak的,因此在self被销毁后这个指针自动被置成nil了,你不用再为之担心,好棒啊..

去掉各种release和autorelease

这个很直接,没有任何问题。去掉就行了~不再多说

讨论一下Property

在MainViewController.m里的类扩展中定义了两个property:


[html]  view plain copy
  1. @interface MainViewController ()  
  2.  @property (nonatomic, retain) NSMutableArray *searchResults;   
  3. @property (nonatomic, retain) SoundEffect *soundEffect;   
  4.  @end  
  5.   
  6. @interface MainViewController ()  
  7. @property (nonatomic, retain) NSMutableArray *searchResults;  
  8. @property (nonatomic, retain) SoundEffect *soundEffect;   
  9. @end  
申明的类型是retain,关于retain,assign和copy的讨论已经烂大 街了,在此不再讨论。在MRC的年代使用property可以帮助我们使用dot notation的时候简化对象的retain和copy,而在ARC时代,这就显得比较多余了。在我看来,使用property和点方法来调用 setter和getter是不必要的。property只在将需要的数据在.h中暴露给其他类时才需要,而在本类中,只需要用实例变量就可以。因此我们 可以移去searchResults和soundEffect的@property和@synthesize,并将起移到实例变量申明中:

[html]  view plain copy
  1. @implementation MainViewController {  NSOperationQueue *queue;    
  2. NSMutableString *currentStringValue; NSMutableArray *searchResults;   
  3. SoundEffect *soundEffect;  }  
  4.   
  5. @implementation MainViewController  
  6. {   
  7.     NSOperationQueue *queue;   
  8.     NSMutableString *currentStringValue;  
  9.     NSMutableArray *searchResults;  
  10.     SoundEffect *soundEffect;   
  11. }  

相应地,我们需要将对应的self.searchResult和 self.soundEffect的self.都去去掉。在这里需要注意的是,虽然我们去掉了soundEffect的property和 synthesize,但是我们依然有一个lazy loading的方法- (SoundEffect *)soundEffect,神奇之处在于(可能你以前也不知道),点方法并不需要@property关键字的支持,虽然大部分时间是这么用的.. (property只是对setter或者getter的申明,而点方法是对其的调用,在这个例子的实现中我们事实上实现了-soundEffect这个 getter方法,所以点方法在等号右边的getter调用是没有问题的)。为了避免误解,建议把self.soundEffect的getter调用改 写成[self soundEffect]。

然后我们看看.h里的property~里面有两个retain的IBOutlet。 retain关键字在ARC中是依旧可用的,它在ARC中所扮演的角色和strong完全一样。为了避免迷惑,最好在需要的时候将其写为strong,那 样更符合ARC的规则。对于这两个property,我们将其申明为weak(事实上,如果没有特别意外,除了最顶层的IBOutlet意外,自己写的 outlet都应该是weak)。通过加载xib得到的用户界面,在其从xib文件加载时,就已经是view hierarchy的一部分了,而view hierarchy中的指向都是strong的。因此outlet所指向的UI对象不应当再被hold一次了。将这些outlet写为weak的最显而易 见的好处是你就不用再viewDidUnload方法中再将这些outlet设为nil了(否则就算view被摧毁了,但是由于这些UI对象还在被 outlet指针指向而无法释放,代码简洁了很多啊..)。

在我们的demo中将IBOutlet的property改为weak并且删掉viewDidUnload中关于这两个IBOutlet的内容~

总结一下新加入的property的关键字类型:

  • strong 和原来的retain比较相似,strong的property将对应__strong的指针,它将持有所指向的对象
  • weak 不持有所指向的对象,而且当所指对象销毁时能将自己置为nil,基本所有的outlet都应该用weak
  • unsafe_unretained 这就是原来的assign。当需要支持iOS4时需要用到这个关键字
  • copy 和原来基本一样..copy一个对象并且为其创建一个strong指针
  • assign 对于对象来说应该永远不用assign了,实在需要的话应该用unsafe_unretained代替(基本找不到这种时候,大部分assign应该都被weak替代)。但是对于基本类型比如int,float,BOOL这样的东西,还是要用assign。

特别地,对于NSString对象,在MRC时代很多人喜欢用copy,而ARC时代一般喜欢用strong…(我也不懂为什么..求指教)

自由桥接的细节

MainViewController现在剩下的问题都是桥接转换问题了~有关桥接的部分有三处:

  • (NSString *)CFURLCreateStringByAddingPercentEscapes(…):CFStringRef至NSString *
  • (CFStringRef)text:NSString *至CFStringRef
  • (CFStringRef)@“!‘();:@&=+$,/?%#[]“:NSString 至CFStringRef

编译器对前两个进行了报错,最后一个是常量转换不涉及内存管理。

关于toll-free bridged,如果不进行细究,NSString和CFStringRef是一样的东西,新建一个CFStringRef可以这么做:

[html]  view plain copy
  1. CFStringRef s1 = [[NSString alloc] initWithFormat:@"Hello, %@!",name];  
  2. 1  
  3. CFStringRef s1 = [[NSString alloc] initWithFormat:@"Hello, %@!",name];  

然后,这里alloc了而s1是一个CF指针,要释放的话,需要这样:

[html]  view plain copy
  1. CFRelease(s1);  
  2. CFRelease(s1);  

相似地可以用CFStringRef来转成一个NSString对象(MRC):

[html]  view plain copy
  1. CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault,bytes, kCFStringEncodingMacRoman);    
  2. NSString *s3 = (NSString *)s2; // release the object when you're done [s3 release];  
  3.   
  4. CFStringRef s2 = CFStringCreateWithCString(kCFAllocatorDefault,bytes, kCFStringEncodingMacRoman);   
  5. NSString *s3 = (NSString *)s2;  
  6. // release the object when you're done  
  7. [s3 release];  

在ARC中,编译器需要知道这些指针应该由谁来负责释放,如果把一个NSObject看做是CF对象的话,那么ARC就不再负责它的释放工作(记住ARC是only for NSObject的)。对于不需要改变持有者的对象,直接用简单的bridge就可以了,比如之前在SoundEffect.m做的转换。在这里对于(CFStringRef)text这个转换,ARC已经负责了text这个NSObject的内存管理,因此这里我们需要一个简单的bridge。 而对于CFURLCreateStringByAddingPercentEscapes方法,方法中的create暗示了这个方法将形成一个新的对象, 如果我们不需要NSString转换,那么为了避免内存的问题,我们需要使用CFRelease来释放它。而这里我们需要一个NSString,因此我们 需要告诉编译器接手它的内存管理工作。这里我们使用bridge_transfer关键字,将内存管理权由CF object移交给NSObject(或者说ARC)。如果这里我们只用bridge 的话,内存管理的负责人没有改变,那么这里就会出现一个内存泄露。另外有时候会看到CFBridgingRelease(),这其实就是transfer cast的内联写法..是一样的东西。总之,需要记住的原则是,当在涉及CF层的东西时,如果函数名中有含有Create, Copy, 或者Retain之一,就表示返回的对象的retainCount+1了,对于这样的对象,最安全的做法是将其放在 CFBridgingRelease()里,来平衡retain和release。

还有一种bridge方式,__bridge_retained。顾名思义,这种转换 将在转换时将retainCount加1。和CFBridgingRelease()相似,也有一个内联方法CFBridgingRetain()来负责 和CFRelease()进行平衡。

需要注意的是,并非所有的CF对象都是自由桥接的,比如Core Graphics中的所有对象都不是自由桥接的(如CGImage和UIImage,CGColor和UIColor)。另外也不是只有自由桥接对象才能用bridge来桥接,一个很好的特例是void (指向任意对象的指针,类似id),对于void 和任意对象的转换,一般使用_bridge。(这在将ARC运用在Cocos2D中很有用)

终于搞定了

至此整个工程都ARC了~对于AFHTTPRequestOperation这样的不 支持ARC的第三方代码,我们的选择一般都是就不使用ARC了(或者等开源社区的大大们更新ARC适配版本)。可以预见,在近期会有越来越多的代码转向 ARC,但是也一定会有大量的代码暂时或者永远保持MRC等个,所以对于这些代码就不用太纠结了~


写在最后

写了那么多,希望你现在能对ARC有个比较全面的了解和认识了。ARC肯定是以后的趋 势,也确实能让代码量大大降低,减少了很多无意义的重复工作,还提高了app的稳定性。但是凡事还是纸上得来终觉浅,希望作为开发者的你,在下一个工程中 去尝试用用ARC~相信你会和我一样,马上爱上这种make life easier的方式的~

YOLOv8改进-利用图像去雾网络UnfogNet提升检测精度的探索【附核心模块代码】 YOLOv8-UnfogNet联合模型的提出为目标检测和图像去雾领域提供了一个新的思路。通过将图像去雾网络和目标检测网络结合,不仅可以提升在恶劣天气下的目标检测精度,还能够为实际应用中的自动驾驶、监控安防等领域带来更强的鲁棒性和适应性。随着去雾技术和目标检测算法的不断发展,我们相信,这种联合方法将在多个领域中获得更加广泛的应用,并为进一步提升图像质量和检测精度做出重要贡献。 阅读详情

相关推荐

手把手教你用CANopen SDO报文控制步进电机(附CIA402协议详解)

本文详细解析了如何通过CANopen SDO报文控制步进电机,深入讲解CIA402协议的核心架构、状态机模型及对象字典管理,并提供实战代码示例。从SDO报文构造到多轴同步控制,帮助开发者掌握工业级步进电机的精确控制技术,适用于自动化设备开发。

weixin_33737774的博客 485

手动内存管理转ARC项目实战

在ARC之前,iOS内存管理无论对资深级还是菜鸟级开发者来说都是一件很头疼的事。我参加过几个使用手动内存管理的项目,印象最深刻的是一个地图类应用,由于应用本身就非常耗内存,当时为了解决内存泄露问题,每周都安排有人值班用Instruments挨个跑功能,关键是每次都总能检查出来不少。其实不管是菜鸟级还是资深级开发者都避免不了写出内存泄露的代码,规则大家都懂,可是天知道什么时候手一抖就少写了个rele

changcunyuan的专栏 570

单片机如何获得5V电源

在单片机实际设计中,有时会需要在电路中用到5V电压源,那么这个常见的实验需求有哪些办法解决呢,我综合网上的资料,概括一下: 1)USB    这种方法在我们直接将单片机板与电脑连接调试的时候,算是简单又方便的办法了,但如果我所要得到的成品不直接连接外部的器件,这就得舍弃。     常用的,USB/5V插头线,这是一种专门的电源线,一端是USB通用接口,可以直插USB端口,另一端是内正外负电压

Echo_Ana的博客 3万+

MRC到ARC的自动转换

  回 到正题,我们讨论的是ARC,关于REST API和XML解析的技术细节就暂时先忽略吧..整个程序都是用MRC来进行内存管理的,首先来让我们把这个demo转成ARC吧。基本上转换为ARC意 味着把所有的retain,release和autorelease关键字去掉,在之前我们明确几件事情: * Xcode提供了一个ARC自动转换工具,可以帮助你将源码转为AR...

靓靓软件工作室 283

在Matlab中开发AutoSAR模型的流程(自下而上)

前面介绍了AutoSAR软件组件开发的两种方式,其中自下向上的方式,是从模型出发,流程如下。

小胡同学的工程师学习之路 5364

一种基于改进YOLOv8并与ORB-SLAM3融合的动态环境密集点云同步定位与建图(SLAM)方法

文章提出了一种基于改进 YOLOv8 与 ORB-SLAM3 融合的动态环境稠密点云 SLAM 方法,通过引入GSConv 卷积模块和VoVGSCSP 特征融合模块优化 YOLOv8 的轻量性,结合实时目标检测与语义分割技术去除动态特征点,显著提升了动态场景下的位姿估计精度。

2401_87345388的博客 1937

iOS开发——MRC(手动内存管理)

iOS开发——MRC(手动内存管理)内存分配区域栈区堆区总结常量区总结代码区总结全局区关于如何查看一个对象在堆区 / 栈区 我们要想了解内存管理的知识前,必须先搞明白计算机的内存分配以及计算机是如何处理内存的。 内存分配区域 内存指的就是RAM(random access memory),内存分配区域主要分为五个区:栈区(系统管理的地方)、堆区(程序员控制的地方)、静态区(全局区)、常量区、代码区。 栈区 栈区(stack)由编译器自动分配并释放,存放的是函数的参数值,局部变量,基本类型的变量和对象引用类型

weixin_51638861的博客 1693

STM32版CCD线性摄像头寻线寻迹小车_stm32接ccd

目前大多数的小车寻线寻迹都是用红外对管寻线,这是比较简单也比较成熟的技术方案,且成本也低。本文将介绍使用CCD线性摄像头寻线寻迹。TSL1401 线性传感器由一个 1x128 的光电二极管阵列、相关的电荷放大电路以及一个内部像素数据保功能组成。内部像素数据保功能可以为所有像素点提供同时积分的开始和停止时间。该阵列由 128 个像素组成,每个像素的感光面积为 3,524.3 平方微米。像素之间的间隔为 8μm。内部控制逻辑简化了操作,该模块需要串行输入(SI)信号和时钟信号(CLK)。

2401_87557129的博客 3228

【iOS】—— MRC

无论是否是自己创建的对象,自己都可以持有,并负责释放。计数器有加就有减。曾经让对象的计数器 +1,就必须在最后让对象计数器 -1。

qq_72437394的博客 1233

基于STM32H750的便携式双通道示波器与信号发生器AFE设计

示波器和信号发生器是电子测量与嵌入式系统调试的基础仪器,其核心在于模拟前端(AFE)对宽动态范围、高精度采样与低失真输出的协同实现。原理上需兼顾输入信号调理(衰减/放大/偏置)、ADC/DAC接口匹配、触发同步及电源完整性设计。技术价值体现在以低成本器件达成±15V输入/±10V输出、16位等效采样精度与85kHz带宽的工程平衡。典型应用场景包括电机驱动波形观测、传感器信号验证、电源环路测试及通信电平分析。本方案聚焦STM32H750平台,深度融合硬件拓扑与片上资源特性,为嵌入式教学与原型开发提供可复现、易

weixin_35755188的博客 107

3、Tone Mapping色调映射(Advanced High Dynamic Range Imaging )

3、Tone Mapping色调映射(Advanced High Dynamic Range Imaging) 如今,大多数可用的显示设备无法本地显示HDR内容。 入门级显示器的对比度仅为200:1。 尽管高端液晶电视具有更高的对比度,但平均对比度约为10,000:1,但通常每个色彩通道的离散度为8位,很少为10位。 这意味着色调限制为255。在过去的二十年中,研究人员花费了大量时间和精力来压缩HDR图像和视频的范围,以便可以在LDR显示器上更“自然”地看到数据。 图3.1 色调映射和真实场景之间.

ISP行业的忠实粉丝 1866

ios arc (四)将mrc代码转成arc

因为可能手上的项目已经用MRC写了一部分,不想麻烦做转变;或者因为新项目里用ARC时遇到了奇怪的问题,从而放弃ARC退回MRC。这都是常见的问题,而在下面,将通过一个demo引导大家彻底转向ARC的世界。 Demo 例子很简单,这是一个查找歌手的应用,包含一个简单的UITableView和一个搜索框,当用户在搜索框搜索时,调用MusicBrainz的API完成名字搜索和匹配。MusicBr

学习笔记 1143

UG NX二次开发(C#)-VS2022配置NX二次开发模板不能正常显示的问题

随着VS2022的发布,使用VS2022进行UG NX二次开发的人员也会越来越多,但是由于VS2022和以前的VS版本采用代码结构不同,而UG NX的二次开发编程模板还没有适应于VS2022的模板配置,所以不能正常的创建一个完整的工程。本文采用曲线救国的方式来实现VS2022下的UG NX二次开发。如果有读者能很好的解决模板配置,不吝赐教。

GimiGimmy 4272

【iOS】MRC与ARC

摘要:Objective-C内存管理机制 Objective-C提供了MRC(手动引用计数)和ARC(自动引用计数)两种内存管理机制。MRC需要开发者手动管理对象生命周期,通过retain/release控制引用计数,易引发内存泄漏和悬挂指针问题。ARC则通过编译器自动插入内存管理代码,简化了开发流程。

2301_80467753的博客 1258

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

iOS——MRC与ARC以及自动释放池深入底层学习

在前面,我们简单学了MRC与ARC。MRC指手动内存管理,需要开发者使用retainrelease等手动管理对象的引用计数,确保对象在必要时被释放。ARC指自动内存管理,由编译器自动管理对象的引用计数,开发者不需要手动管理内存。这是因为。

m0_73348697的博客 1554

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

iOS——MRC和ARC实现原理

Objective-C提供了两种内存管理机制MRC(MannulReferenceCounting)和ARC(AutomaticReferenceCounting),为Objective-C提供了内存的手动和自动管理。下面我们来探讨一下MRC和ARC的实现。

LANGJ1的博客 2077

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

MRC和ARC

MRC和ARC是两种设计模式 1.MRC设计模式 MRC:Manul Reference Counting(手动引用计数) 需要手动管理内存,即手动添加release/retain等内存管理代码,否则,会造成内存泄露 具体的内存管理方法见文章iOS内存管理 2.ARC设计模式 ARC:Automatical Reference Counting(自动引用计数) iOS中的垃圾回收机制跟其它语言不同...

superyuan567的博客 677

Objective-c的内存管理MRC与ARC

Objective-c中提供了两种内存管理机制MRC(MannulReference Counting)和ARC(Automatic Reference Counting),分别提供对内存的手动和自动管理,来满足不同的需求。注意的是Xcode 4.1及其以前版本没有ARC,MRC与ARC的区别如图1所示。需要理解MRC,但实际使用时强推ARC。 图1  MRC与ARC区别示意图

Fighting Bull 4万+

xcode的ARC和MRC切换

Xcode5之后,新建iOS工程,默认都是ARC模式,但是有时候我们的项目中需要用到一些第三方框架,我们下载下来却发现是非ARC的,这时候我们需要进行ARC和MRC混编 第一种方式,Edit->Refactor,转换成ARC方式 著名的iOS网络框架ASIHTTPRequest就是MRC,我们试试能不能转换成ARC 点击Check,我们发现悲剧了

vkjs8imde的博客 4272

MRC 和 ARC的区别

iOS 知识点1.MRC 和 ARCObjective-c中提供了两种内存管理机制 MRC(Manual Reference Counting):手动内存管理 ARC(Automatic Reference Counting):自动内存管理

jeikerxiao 4870

ARC和MRC下Block的使用注意

Block 1.是一段代码块,只在被调用的时候执行(类似于方法和函数) 2.是一种数据类型(类似于’int’,’NSString’) 3.可以定义成临时变量 4.可以当做参数传递 5.可以定义成属性 6.是一种匿名函数(重要,只有函数体,没有函数名) 7.是一个指向函数的指针(一个指针对象,block的名字就是指针的地址) 8.因为block代码块的内部没有修改和访问外部的变量,所...

LIN1986LIN的专栏 629

MRC工程转ARC工程小记

春节前抽空花了一天的时间将手头的工程从MRC转成了ARC,然后陆陆续续地修复一部分因为转ARC引起的内存泄漏和崩溃,到目前为止工程也算是比较稳定了,抽空记上一笔。(虽说这种事情这辈子估计都只会做这么一次了,但是可以留点经验给后来的童鞋) 这个工程启动于12年底13年初,一开始人手少工期短,需要尽快地出demo,同时抱着对面世才一年多的ARC不太信任的态度沿用了最熟悉的MRC。但是随着工程投入

 仗剑走天涯 1117

ARC MRC的对比

self-love-553243_640.jpg MRC似乎已经是一个上古时代的话题了,不过我还是绕有兴致的把它翻出来。因为,今天我被一个问题问住了:ARC与MRC的性能方面孰优劣。确实,之前没有对比过。 先来做个测试吧。首先我们需要一个计时辅助函数,我选择使用mach_absolute_time,计算时间差的函数如下: double subtractTimes(uint64_t e

qq_28703891的博客 702

ARC与MRC的性能对比

MRC似乎已经是一个上古时代的话题了,不过我还是绕有兴致的把它翻出来。因为,今天我被一个问题问住了:ARC与MRC的性能方面孰优劣。确实,之前没有对比过。 先来做个测试吧。首先我们需要一个计时辅助函数,我选择使用mach_absolute_time,计算时间差的函数如下: 1 2 3 4 5 6 7 8 9

qq_16379603的博客 778

ARC,MRC理解

1/*     oc里面有三种  ARC MRC gc    java里面有垃圾回收机制  1. 人工引用计数-MRC(MannulReference Counting)  2. 自动引用计数-ARC(AutomaticReference Counting)  在MRC的内存管理模式下,与对变量的管理相关的方法有:retain,release和autorelease。retain和r

SoundsGood的博客 621
上一篇: OC中的NSFoundation框架
下一篇: iOS 中的本地推送实现
Shicuf
博客等级 码龄16年 11粉丝 66原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值