在ARC之前,我有以下代码在异步操作正在进行时保留委托:
- (void)startAsyncWork
{
[_delegate retain];
// calls executeAsyncWork asynchronously
}
- (void)executeAsyncWork
{
// when finished, calls stopAsyncWork
}
- (void)stopAsyncWork
{
[_delegate release];
}
Run Code Online (Sandbox Code Playgroud)
ARC的这种模式相当于什么?
memory-management objective-c ios ios5 automatic-ref-counting
我有一个非ARC项目,它使用支持ARC的静态库.这是一个受支持的方案,所以一切正常.也就是说,直到我在4.x设备上运行代码,包括模拟器.在这种情况下,代码会出现以下链接器错误:
dyld: lazy symbol binding failed: Symbol not found: _objc_storeStrong
Referenced from: /Users/zoul/Library/Application Support/iPhone Simulator/4.3.2/Applications/…/Demo.app/Demo
Expected in: /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator4.3.sdk/System/Library/Frameworks/Foundation.framework/Foundation
Run Code Online (Sandbox Code Playgroud)
只要某些启用ARC的代码尝试调用_objc_storeStrong函数,就会发生这种情况,就像在initmethod(self = [super init])中一样.将主项目转换为ARC可以解决问题,但我想知道是否还有其他解决方案.
我有以下代码,并在编译之前收到此错误:
默认情况下,无法在ARC中修改快速枚举变量,声明变量_strong以允许此变量
for (NSString *name in array){
@try {
S3ObjectController *localS3 = [[S3ObjectController alloc]init];
name = localS3.stringProperty;
}
Run Code Online (Sandbox Code Playgroud)
在这个S3ObjectController类中,我有如下声明的属性:
@property (nonatomic, strong) NSString *stringProperty;
Run Code Online (Sandbox Code Playgroud)
我该如何更改房产?我以为我声称它很强大?
所以我在我的项目中使用ARC,当我添加一个AVPlayerLayer时,它工作得很好,但是当我从UINavigationItem弹出UIViewController时,视频继续在后台播放.有谁知道你会如何处理这个?这似乎很简单,我只是俯瞰.这是我最初实例化的代码.
self.currentItem = [[AVPlayerItem alloc] initWithURL:url];
self.player = [[AVPlayer alloc]initWithPlayerItem:self.currentItem];
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
self.avPlayerLayer.bounds = self.view.bounds;
self.avPlayerLayer.frame = CGRectMake(0,55, 1024, 670);
self.view.backgroundColor = [UIColor clearColor];
[self.view.layer addSublayer:avPlayerLayer];
Run Code Online (Sandbox Code Playgroud)
这也是我如何确定属性的方式.
@property (strong) AVPlayer *player;
@property (strong) AVPlayerLayer *avPlayerLayer;
@property (strong) AVPlayerItem *currentItem;
Run Code Online (Sandbox Code Playgroud)
也许这完全错了.我不确定何时使用(强)vs(弱).任何情况下都要提前感谢您的帮助.
我正在尝试将旧项目转换为ARC.我有一个创建UUID的函数,但显然在使用ARC时不再支持:
NSString *uuid = nil;
CFUUIDRef theUUID = CFUUIDCreate(kCFAllocatorDefault);
if (theUUID) {
uuid = NSMakeCollectable(CFUUIDCreateString(kCFAllocatorDefault, theUUID));
//[uuid autorelease];
CFRelease(theUUID);
}
Run Code Online (Sandbox Code Playgroud)
我收到编译器错误(尝试转换时):'NSMakeCollectable'不可用:在自动引用计数模式下不可用.
所以我的问题是:如何在使用ARC时创建UUID?还有其他方法我现在应该使用吗?
是否有可能在没有__weak对象的块中传递[self anyFunction]?
作为示例,这是来自System Framework的有效代码:
[UIView animateWithDuration:0.8 animations:^{
//Do animationStuff
} completion:^(BOOL finished) {
[self anyFunction];
}];
Run Code Online (Sandbox Code Playgroud)
您可以[self anyFunction]在没有警告的情况下传入完成块.但是如果使用完成块编写自己的方法,则会出现以下警告:在此块中强烈捕获"self"可能会导致保留周期.
工作解决方案非常简单(iOS 5 + ARC).在块声明之前:
__weak MyClass *weakSelf = self;
Run Code Online (Sandbox Code Playgroud)
在完成块中你必须打电话:
[weakSelf anyFunction];
Run Code Online (Sandbox Code Playgroud)
但是,回到我的问题:为什么System Framework API中不需要使用__weak对象并在self没有任何警告的情况下使用.以及如何__weak在块中不需要对象的情况下实现方法?
感谢你的付出.
iphone objective-c ios objective-c-blocks automatic-ref-counting
我刚刚偶然发现了以下SO主题:我们为什么要复制块而不是保留?其中包含以下句子:
但是,从iOS 6开始,它们被视为常规对象,因此您无需担心.
我真的很困惑这个断言,这就是为什么我要问:这个断言是否真的暗示Objective-C开发人员不需要
@property (copy) blockProperties 要么
[^(...){...) {} copy]
将块及其内容从堆栈复制到堆中了吗?
我希望我所做的描述很清楚.
请详细说明.
类似的问题
当你读到这里在大多数情况下,IBOutlet应该是弱.
现在,您可以在开发库中阅读并非所有类都支持弱引用.(例如NSTextView).这意味着您必须使用assign:
@property (assign) IBOutlet NSTextView *textView;
Run Code Online (Sandbox Code Playgroud)
如果使用弱引用,您将收到以下错误:"不允许合成弱不可用属性,因为它需要合成__weak对象的ivar"
文档错过的内容是现在你必须在使用后再将属性设置为nil,例如通过一种dealloc方法:
- (void)dealloc
{
self.textView = nil;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,标NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE有的类不支持弱引用,但原因是什么?
在阅读了Mike Ash的优秀博客文章"星期五Q&A 2014-05-09:当Autorelease不是"时,我决定查看ARC应用于加速保留/释放过程的优化的详细信息.我所指的技巧称为"快速自动释放",其中调用者和被调用者合作以将返回的对象保持在自动释放池之外.这在以下情况下效果最佳:
- (id) myMethod {
id obj = [MYClass new];
return [obj autorelease];
}
- (void) mainMethod {
obj = [[self myMethod] retain];
// Do something with obj
[obj release];
}
Run Code Online (Sandbox Code Playgroud)
可以通过完全跳过自动释放池来优化:
- (id) myMethod {
id obj = [MYClass new];
return obj;
}
- (void) mainMethod {
obj = [self myMethod];
// Do something with obj
[obj release];
}
Run Code Online (Sandbox Code Playgroud)
实现此优化的方式非常有趣.我引用Mike的帖子:
"在Objective-C运行时自动释放的实现中有一些非常奇特且令人费解的代码.在实际发送自动释放消息之前,它首先检查调用者的代码.如果它看到调用者将立即调用objc_retainAutoreleasedReturnValue,那么它完全是跳过消息发送.它实际上根本不进行自动释放.相反,它只是将对象存储在已知位置,这表示它根本没有发送自动释放."
到现在为止还挺好.NSObject.mm上的x86_64实现非常简单.代码分析位于返回地址之后的汇编程序,objc_autoreleaseReturnValue以便存在调用objc_retainAutoreleasedReturnValue.
static bool callerAcceptsFastAutorelease(const void * const ra0)
{
const …Run Code Online (Sandbox Code Playgroud) assembly memory-management objective-c ios automatic-ref-counting
使用惰性初始化器时,是否有可能保留周期?
在博客文章和许多其他地方[unowned self]可见
class Person {
var name: String
lazy var personalizedGreeting: String = {
[unowned self] in
return "Hello, \(self.name)!"
}()
init(name: String) {
self.name = name
}
}
Run Code Online (Sandbox Code Playgroud)
我试过这个
class Person {
var name: String
lazy var personalizedGreeting: String = {
//[unowned self] in
return "Hello, \(self.name)!"
}()
init(name: String) {
print("person init")
self.name = name
}
deinit {
print("person deinit")
}
}
Run Code Online (Sandbox Code Playgroud)
像这样使用它
//...
let person = Person(name: "name")
print(person.personalizedGreeting)
//..
Run Code Online (Sandbox Code Playgroud)
并发现"人员deinit"被记录下来.
所以似乎没有保留周期.根据我的知识,当一个块捕获自我并且当该块被自己强烈保留时,存在保留周期.这种情况看起来类似于保留周期但实际上并非如此.
memory-leaks memory-management lazy-initialization automatic-ref-counting swift
objective-c ×7
ios ×5
iphone ×2
assembly ×1
avplayer ×1
cocoa-touch ×1
enumeration ×1
iboutlet ×1
ios5 ×1
memory-leaks ×1
nstextview ×1
properties ×1
swift ×1
weak ×1
xcode ×1