Emi*_*ier 68 objective-c ios4 ios5 automatic-ref-counting
我需要在NSArray中存储对象的弱引用,以防止保留周期.我不确定使用正确的语法.这是正确的方法吗?
Foo* foo1 = [[Foo alloc] init];
Foo* foo2 = [[Foo alloc] init];
__unsafe_unretained Foo* weakFoo1 = foo1;
__unsafe_unretained Foo* weakFoo2 = foo2;
NSArray* someArray = [NSArray arrayWithObjects:weakFoo1, weakFoo2, nil];
Run Code Online (Sandbox Code Playgroud)
请注意,我需要支持iOS 4.x,__unsafe_unretained而不是__weak.
编辑(2015-02-18):
对于那些想要使用真__weak指针(不是__unsafe_unretained)的人,请查看这个问题:在ARC下归零弱引用
yuj*_*uji 73
正如杰森所说,你不能使NSArray商店弱参考.实现Emile建议将对象包装在另一个存储弱引用的对象内的最简单方法如下:
NSValue *value = [NSValue valueWithNonretainedObject:myObj];
[array addObject:value];
Run Code Online (Sandbox Code Playgroud)
另一种选择:一个类别,使得NSMutableArray可选地存储弱引用.
请注意,这些是"不安全的未保留"引用,而不是自置零弱引用.如果在释放对象后数组仍然存在,那么你将拥有一堆垃圾指针.
Tho*_*ann 55
使用NSValue帮助程序或创建集合(数组,集合,字典)对象并禁用其Retain/Release回调的解决方案都不是关于使用ARC的100%故障安全解决方案.
正如对这些建议的各种评论所指出的,这样的对象引用不会像真正的弱引用那样工作:
ARC支持的"适当"弱属性有两种行为:
现在,虽然上述解决方案符合行为#1,但它们没有展示#2.
要获得行为#2,您必须声明自己的帮助程序类.它只有一个弱的属性来保持你的参考.然后,将此辅助对象添加到集合中.
哦,还有一件事:iOS6和OSX 10.8据称可以提供更好的解决方案:
[NSHashTable weakObjectsHashTable]
[NSPointerArray weakObjectsPointerArray]
[NSPointerArray pointerArrayWithOptions:]
Run Code Online (Sandbox Code Playgroud)
这些应该给你容纳弱引用的容器(但请注意下面的matt的评论).
Ric*_*ges 25
在编写c ++ 20年后,我是Objective-C的新手.
在我看来,Objective-C在松散耦合的消息传递方面非常出色,但在数据管理方面却很糟糕.
想象一下,我发现xcode 4.3支持objective-c ++是多么高兴!
所以现在我将所有.m文件重命名为.mm(编译为objective-c ++)并使用c ++标准容器进行数据管理.
因此,"弱指针数组"问题成为__weak对象指针的std :: vector:
#include <vector>
@interface Thing : NSObject
@end
// declare my vector
std::vector<__weak Thing*> myThings;
// store a weak reference in it
Thing* t = [Thing new];
myThings.push_back(t);
// ... some time later ...
for(auto weak : myThings) {
Thing* strong = weak; // safely lock the weak pointer
if (strong) {
// use the locked pointer
}
}
Run Code Online (Sandbox Code Playgroud)
这等同于c ++习语:
std::vector< std::weak_ptr<CppThing> > myCppThings;
std::shared_ptr<CppThing> p = std::make_shared<CppThing>();
myCppThings.push_back(p);
// ... some time later ...
for(auto weak : myCppThings) {
auto strong = weak.lock(); // safety is enforced in c++, you can't dereference a weak_ptr
if (strong) {
// use the locked pointer
}
}
Run Code Online (Sandbox Code Playgroud)
概念证明(根据Tommy对矢量重新分配的担忧):
main.mm:
#include <vector>
#import <Foundation/Foundation.h>
@interface Thing : NSObject
@end
@implementation Thing
@end
extern void foo(Thing*);
int main()
{
// declare my vector
std::vector<__weak Thing*> myThings;
// store a weak reference in it while causing reallocations
Thing* t = [[Thing alloc]init];
for (int i = 0 ; i < 100000 ; ++i) {
myThings.push_back(t);
}
// ... some time later ...
foo(myThings[5000]);
t = nullptr;
foo(myThings[5000]);
}
void foo(Thing*p)
{
NSLog(@"%@", [p className]);
}
Run Code Online (Sandbox Code Playgroud)
示例日志输出:
2016-09-21 18:11:13.150 foo2[42745:5048189] Thing
2016-09-21 18:11:13.152 foo2[42745:5048189] (null)
Run Code Online (Sandbox Code Playgroud)
Eri*_*ner 13
如果您不需要特定订单,则可以使用NSMapTable特殊键/值选项
NSPointerFunctionsWeakMemory
使用适合ARC或GC的弱读写屏障.使用NSPointerFunctionsWeakMemory对象引用将在上次发布时变为NULL.
Yan*_*der 11
我相信最好的解决方案是使用NSHashTable或NSMapTable.键或/和值可能很弱.你可以在这里阅读更多相关信息:http://nshipster.com/nshashtable-and-nsmaptable/
| 归档时间: |
|
| 查看次数: |
41962 次 |
| 最近记录: |