I am new to objective-C, after 20 years of writing c++.
In my view, objective-C is excellent at loosely-coupled messaging, but horrible for data management.
Imagine how happy I was to discover that xcode 4.3 supports objective-c++!
So now I rename all my .m files to .mm (compiles as objective-c++) and use c++ standard containers for data management.
Thus the "array of weak pointers" problem becomes a std::vector of __weak object pointers:
#include <vector>@interface Thing : NSObject@end// declare my vectorstd::vector<__weak Thing*> myThings;// store a weak reference in itThing* 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 }}
Which is equivalent to the c++ idiom:
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 }}
Proof of concept (in the light of Tommy's concerns about vector reallocation):
main.mm:
#include <vector>#import <Foundation/Foundation.h>@interface Thing : NSObject@end@implementation Thing@endextern 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]);}
example log output:
2016-09-21 18:11:13.150 foo2[42745:5048189] Thing2016-09-21 18:11:13.152 foo2[42745:5048189] (null)