我是iOS开发的新手,从未处理过手动引用计数(保留,释放,自动释放).因此,我对ARC的神奇表现并不了解.
我想我明白,直到有人问我是什么所有制类型(weak,strong,assign应给予一个只读属性的对象指向,如,等):
@property (readonly,nonatomic) NSString* name;
Run Code Online (Sandbox Code Playgroud)
我读到这里
关于ARC只读@property问题,离开关strong/ weak不实际编译除非你指定了后备变量时,你@synthesize的财产; 我恰巧正在指定这样的支持ivar:
@synthesize name = _name;
Run Code Online (Sandbox Code Playgroud)
现在我明白变量的默认'生命周期限定符'很强,从这里开始:http://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/DOC/UID/TP40011226-CH1-SW4
所以简而言之 - 我间接地定义了我的财产,(readonly,nonatomic,strong)因为_nameivar被隐含地声明为__strong.
我有几个问题:
是否strong使用正确的终身限定符?我认为它是,否则支持我的对象NSString*将不会被拥有在任何地方,因此将自动释放(来自Java领域这是有道理的,因为默认情况下所有引用都很强).
在这种情况下是否还有其他修饰符,例如copy或assign?
声明财产是否(readonly,nonatomic,strong)与消耗财产(readonly,nonatomic)的代码有任何区别?例如.并宣布它不关键字导致待存储的对象作为指针,其中属性将被存储在一个指针?strong__unsafe_unretainedstrong__strong
谢谢!
编辑
据我所知,以下适用于readonly属性:
(readonly, assign).(readonly, strong)或(readonly, copy)- 这些函数与readonly属性相同,但如果扩展/子类并将属性重新声明为,则可能需要复制语义readwrite.(readonly, …properties object objective-c readonly automatic-ref-counting
我知道iOS自动引用计数,它是基于编译器的功能.但是,我一直在浏览许多网站,并对iOS程序开发中是否存在垃圾收集感到困惑?我知道,ARC和GC彼此不同.一些链接说,GC可用于iOS,有些链接表示GC仅适用于Mac OS X开发.但是,我无法断定在iOS开发中是否存在GC?请指导我正确的路径或链接,以便我能理解它并尝试编程.
谢谢!
我们是否必须removeObserver:明确发送已作为观察者添加到NSNotificationCenter之前的对象?
我有点困惑,无法找到确切的答案.
请详细提供我,包括为什么我们需要显式删除Observer,以及为什么编译器没有隐式地将它放在类/应用程序中?
cocoa objective-c nsnotificationcenter automatic-ref-counting
如果我声明这样的属性:
@property(nonatomic,weak) Foo *someProperty;
Run Code Online (Sandbox Code Playgroud)
然后我声明一个自定义setter,如下所示:
- (void)setSomeProperty:(Foo *)someProp {
_someProperty = someProp;
//...more custom stuff
}
Run Code Online (Sandbox Code Playgroud)
这有什么不对吗?也就是说,编译器应该自动使用__weak修饰符合成_someProperty ivar,所以只需在上面的setter中进行赋值就足够了,对吗?
我想知道是否有人使用SFHFKeychainUtils设法修改它们以兼容ARC.更确切地说
NSDictionary *attributeResult = NULL;
NSMutableDictionary *attributeQuery = [query mutableCopy];
[attributeQuery setObject: (id) kCFBooleanTrue forKey:(__bridge id) kSecReturnAttributes];
OSStatus status = SecItemCopyMatching((CFDictionaryRef) attributeQuery,(CFTypeRef *)(attributeResult));
Run Code Online (Sandbox Code Playgroud)
我试过了
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) attributeQuery,(CFTypeRef *)(attributeResult));
Run Code Online (Sandbox Code Playgroud)
也
CFTypeRef subAttributeResult = (CFTypeRef *)(objc_unretainedPointer(attributeResult));
OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef) attributeQuery,(CFTypeRef *)(subAttributeResult));
Run Code Online (Sandbox Code Playgroud)
这2个是我设法得到的唯一两种方法没有错误.通过在这里添加objc_XXX而不是CFTypeRef来实现任何其他方法并且在那里得到错误(从ARC中禁止从obj-c指针到CFTypeRef的隐式转换,将x参数传递给y参数丢弃限定符).显然,第一段代码也会出错.虽然构建时没有出现任何错误,但在到达此部分代码时,应用程序会因EXC_BAD_ACCESS而崩溃.
完整SFHFKeychainUtils的链接:https://github.com/ldandersen/scifihifi-iphone/tree/master/security
有什么帮助吗?谢谢.
iphone keychain ios automatic-ref-counting sfhfkeychainutils
我正在编写一个涉及事件处理的API,我希望能够为处理程序使用块.回调通常需要访问或修改self.在ARC模式中,Clang警告说引用self的块可能会创建一个保留周期,这似乎是一个有用的警告,我想继续保持.
但是,对于我的这部分API,回调的生命周期和包含对象在外部进行维护.我知道当对象应该被释放时我可以打破循环.
我可以在每个文件的基础上关闭保留周期警告#pragma clang diagnostic ignored "-Warc-retain-cycles",但是会禁用整个文件的警告.我可以围绕一个块#pragma clang diagnostic push和pop周围的警告,但是这使得该块难看.
我还可以通过引用指向self的__weak变量而不是直接引用self来获取警告消失,但这使得块使用起来不那么令人愉快.
我提出的最好的解决方案是这个宏在块周围执行诊断禁用:
#define OBSERVE(OBJ, OBSERVEE, PATH, CODE) \
[(OBJ) observeObject:(OBSERVEE) forKeyPath:(PATH) withBlock:^(id obj, NSDictionary *change) { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-retain-cycles\"") \
do { CODE; } while(0); \
_Pragma("clang diagnostic pop") \
}];
Run Code Online (Sandbox Code Playgroud)
这是有效的,但它对于API用户来说不是很容易被发现,它不允许嵌套的观察者,并且它与XCode的编辑器交互不良.有没有更好的方法来禁用或避免警告?
所以我正在使用递归块.我理解,对于要递归的块,它需要以__block关键字开头,并且必须将其复制,以便将其放在堆上.但是,当我这样做时,它显示为仪器中的泄漏.有谁知道为什么或如何绕过它?
请注意,在下面的代码中,我已经引用了许多其他块,但它们都不是递归的.
__block NSDecimalNumber *(^ProcessElementStack)(LinkedList *, NSString *) = [^NSDecimalNumber *(LinkedList *cformula, NSString *function){
LinkedList *list = [[LinkedList alloc] init];
NSDictionary *dict;
FormulaType type;
while (cformula.count > 0) {
dict = cformula.pop;
type = [[dict objectForKey:@"type"] intValue];
if (type == formulaOperandOpenParen || type == formulaListOperand || type == formulaOpenParen) [list add:ProcessElementStack(cformula, [dict objectForKey:@"name"])];
else if (type == formulaField || type == formulaConstant) [list add:NumberForDict(dict)];
else if (type == formulaOperand) [list add:[dict objectForKey:@"name"]];
else if (type == formulaCloseParen) {
if (function){ …Run Code Online (Sandbox Code Playgroud) objective-c instruments objective-c-blocks automatic-ref-counting
我刚刚将我的应用程序转换为ARC,并且在构建正常的时候,我得到600个警告,所有这些都与我的属性有关.如:
默认属性属性'assign'不适合非gc对象
未指定"assign","retain"或"copy"属性 - 假定为"assign"
在Xcode转换我的代码之后,这是我的属性的样子:
@property (nonatomic) EKEventStore *eventStore;
@property (nonatomic) EKCalendar *defaultCalendar;
@property (nonatomic) UIActionSheet *currentActionSheet;
@property (nonatomic) UILabel *noEventLabel;
Run Code Online (Sandbox Code Playgroud)
有人谈到需要添加strong所有这些.是这样的吗?Xcode忘了添加一些东西吗?
我最近开始使用ARC,从那时起我就把它归咎于每一个内存问题.:)也许,你可以帮助我更好地理解我做错了什么.
我目前的项目是关于CoreGraphics的很多 - 图表绘图,填充缩略图的视图等等.我相信在使用手动内存管理时没有任何问题,除了可能是一些僵尸......但截至目前,每当我尝试创建大量缩略图或重绘更复杂的图表时,应用程序就会崩溃.
在使用Instruments进行分析时,我可以看到驻留内存和脏内存中的非常高的值.堆分析表明相当惊人的不规则增长...
只绘制几个缩略图时,常驻内存增长约200 MB.绘制完所有内容后,内存将恢复与绘制前几乎相同的值.但是,有很多缩略图,驻留内存中的值高于400 MB,这显然会导致应用程序崩溃.我试图限制同时绘制的缩略图数量(NSOperationQueue及其maxConcurrentOperationCount),但由于释放这么多内存似乎需要花费更多时间,所以它并没有真正解决问题.
现在我的应用程序基本上不起作用,因为真实的数据适用于许多复杂的图表=很多缩略图.
每个缩略图都是用我从这里得到的代码创建的:( UIImage上的类别)
+ (void)beginImageContextWithSize:(CGSize)size
{
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
if ([[UIScreen mainScreen] scale] == 2.0) {
UIGraphicsBeginImageContextWithOptions(size, YES, 2.0);
} else {
UIGraphicsBeginImageContext(size);
}
} else {
UIGraphicsBeginImageContext(size);
}
}
+ (void)endImageContext
{
UIGraphicsEndImageContext();
}
+ (UIImage*)imageFromView:(UIView*)view
{
[self beginImageContextWithSize:[view bounds].size];
BOOL hidden = [view isHidden];
[view setHidden:NO];
[[view layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
[self endImageContext];
[view setHidden:hidden];
return image;
}
+ (UIImage*)imageFromView:(UIView*)view scaledToSize:(CGSize)newSize
{
UIImage *image …Run Code Online (Sandbox Code Playgroud) 在Apple关于ARC的文档中,他们提出了一个有问题的场景,其中ARC将在幕后生成样板临时变量.搜索"编译器因此重写":
警告的要点似乎是因为基于堆栈的变量是"强"并且被调用方法的by-reference参数(performOperationWithError :)是自动释放的,ARC将生成一个临时局部变量来满足内存管理需求自动释放变量.但是因为临时变量被分配给样板示例中的强变量,所以从客户的角度来看似乎没有风险.
究竟是什么文件在这里向我们发出警告?作为客户端或可以以这种方式调用的方法的实现者(具有自动释放的,按值返回参数)的风险是什么?
objective-c ×8
ios ×5
cocoa ×2
properties ×2
clang ×1
instruments ×1
iphone ×1
keychain ×1
macos ×1
object ×1
readonly ×1
warnings ×1
xcode ×1