objc_setAssociatedObject() और दोस्तों के iPhone OS 3.1 में जोड़ा गया था, ताकि आप वास्तव में हिमपात तेंदुए पर के रूप में सटीक एक ही बात कर सकते हैं अगर आप सिर्फ 3.1+ उपकरणों लक्ष्यीकरण का विकल्प होता है ...
आप तो क्या आप NSObjects dealloc विधि से एसोसिएशन और बंदर पैच का स्थिर शब्दकोश नहीं बना सकते हैं। विभिन्न तकनीकी कारणों से इस समाधान जीसी की उपस्थिति (जिसके कारण सेब संघ सामान जोड़ा) में सही ढंग से काम करने के लिए नहीं किया जा सकता है, लेकिन iPhone जीसी है कि एक गैर मुद्दा है का समर्थन नहीं करता क्योंकि।
तुम सिर्फ इस परियोजना मैं अत्यधिक क्रम कार्यों का उपयोग करने और लक्षित कर 3.1 प्लस की सिफारिश पर काम शुरू कर रहे हैं, लेकिन यह है कि अगर नहीं है यहाँ एक विकल्प तुम कैसे करते का एक उदाहरण है।
LGAssociativeStorage.h:
#import <pthread.h>
#import <Foundation/Foundation.h>
@interface NSObject (LGAssociativeStorage)
@property (retain) id associatedObject;
@end
LGAssociativeStorage.mm
#import <objc/runtime.h>
#import "LGAssociativeStorage.h"
/* We are using STL containers because:
1) Using Objective C containers can cause deallocs which cause recursion issues
2) STL containers are high perf containers that don't introduce external code dependencies
Ideally one could include a thread safe map implementation, but I don't need one currently
*/
#include <map>
typedef std::map<id,id> idMap_t;
typedef std::pair<id,id> idPair_t;
static NSMutableDictionary * data = nil;
static pthread_mutex_t data_lock = PTHREAD_MUTEX_INITIALIZER;
static IMP gOriginalNSObjectDealloc = nil;
static idMap_t associatedObjectMap;
static
void removeAssociatedObjectFromMap(id self) {
idMap_t::iterator iter = associatedObjectMap.find(self);
if(iter != associatedObjectMap.end()) {
[iter->second release];
associatedObjectMap.erase(iter);
}
}
static
id newNSObjectDealloc(id self, SEL deallocSelector, ...) {
pthread_mutex_lock(&data_lock);
removeAssociatedObjectFromMap(self);
pthread_mutex_unlock(&data_lock);
return gOriginalNSObjectDealloc(self, deallocSelector);
}
static void initIfNecessary(void) {
if (!data) {
data = [[NSMutableDictionary alloc] init];
// The below line of code is abusive... in the future the Objective C runtime will use it as evidence
// that I am an unfit software engineer and take custody of all my code
gOriginalNSObjectDealloc = class_replaceMethod([NSObject class], @selector(dealloc), newNSObjectDealloc, "[email protected]:");
}
}
@implementation NSObject (LGAssociativeStorage)
- (id) associatedObject {
id retval = nil;
pthread_mutex_lock(&data_lock);
initIfNecessary();
idMap_t::iterator iter = associatedObjectMap.find(self);
if(iter != associatedObjectMap.end()) {
retval = iter->second;
}
pthread_mutex_unlock(&data_lock);
return retval;
}
- (void) setAssociatedObject:(id)object_ {
pthread_mutex_lock(&data_lock);
initIfNecessary();
removeAssociatedObjectFromMap(self);
[object_ retain];
associatedObjectMap.insert(idPair_t(self, object_));
pthread_mutex_unlock(&data_lock);
}
@end
स्रोत
2009-09-11 07:33:59
हां, किसी भी अतिरिक्त रन-टाइम दिनचर्या के बिना श्रेणी के माध्यम से इवर एक्सटेंशन का अनुकरण करना संभव है। [यहां] (http://stackoverflow.com/questions/4887004/category-like-extension-for-instance-variables/4899521#4899521) मेरा वर्णन कैसे है। –