Я новичок в Objective-C, после 20 лет написания C ++.
На мой взгляд, target-C отлично подходит для слабо связанных сообщений, но ужасен для управления данными.
Представьте, как я был рад обнаружить, что xcode 4.3 поддерживает Objective-C ++!
Итак, теперь я переименовываю все мои файлы .m в .mm (компилируется как target-c ++) и использую стандартные контейнеры c ++ для управления данными.
Таким образом, проблема «массива слабых указателей» становится std :: vector __weak указателей объекта:
#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
}
}
Что эквивалентно идиоме 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
}
}
Подтверждение концепции (в свете озабоченности Томми по поводу перераспределения векторов):
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]);
}
пример вывода журнала:
2016-09-21 18:11:13.150 foo2[42745:5048189] Thing
2016-09-21 18:11:13.152 foo2[42745:5048189] (null)