Non-retaining array for delegates

后端 未结 10 1358
感动是毒
感动是毒 2020-11-29 18:41

In a Cocoa Touch project, I need a specific class to have not only a single delegate object, but many of them.

It looks like I should create an NSArray for these del

相关标签:
10条回答
  • 2020-11-29 19:09

    I'd suggest to not-fight-the-framework and use NSPointerArray with the NSPointerFunctionsWeakMemory NSPointerFunctionOption like this:

    NSPointerArray *weakReferencingArray = [NSPointerArray pointerArrayWithOptions:NSPointerFunctionsWeakMemory];
    
    // NSPointerFunctionsWeakMemory - Uses weak read and write barriers 
    // appropriate for ARC or GC. Using NSPointerFunctionsWeakMemory 
    // object references will turn to NULL on last release.
    

    Served me well in scenarios, where I had to design a delegates array, which auto-NULL's references.

    0 讨论(0)
  • 2020-11-29 19:09

    I found an open source library named XMPPFramewrok

    There is a multicast delegate solution in the project

    https://github.com/robbiehanson/XMPPFramework/wiki/MulticastDelegate

    0 讨论(0)
  • 2020-11-29 19:13

    I am presenting an important limitation of one of the earlier answers, along with an explanation and an improvement.

    Johnmph suggested using [NSValue valueWithNonretainedObject:].

    Note that when you do this, your reference acts not like __weak, but rather like __unsafe_unretained while inside the NSValue object. More specifically, when you try to get your reference back (using [myNSValue nonretainedObjectValue]), your application will crash with an EXC_BAD_ACCESS signal if the object has been deallocated before that time!

    In other words, the weak reference is not automatically set to nil while inside the NSValue object. This took me a bunch of hours to figure out. I have worked around this by creating a simple class with only a weak ref property.

    More beautifully, by using NSProxy, we can treat the wrapper object entirely as if it is the contained object itself!

    // WeakRef.h
    @interface WeakRef : NSProxy
    
    @property (weak) id ref;
    - (id)initWithObject:(id)object;
    
    @end
    
    
    // WeakRef.m
    @implementation WeakRef
    
    - (id)initWithObject:(id)object
    {
        self.ref = object;
        return self;
    }
    
    - (void)forwardInvocation:(NSInvocation *)invocation
    {
        invocation.target = self.ref;
        [invocation invoke];
    }
    
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
    {
        return [self.ref methodSignatureForSelector:sel];
    }
    
    @end
    
    0 讨论(0)
  • 2020-11-29 19:19

    Keyword: NSHashTable, search in documentations.

    0 讨论(0)
  • 2020-11-29 19:19

    What about storing in the array or dictionary

    __weak typeof(pointer) weakPointer = pointer;
    
    0 讨论(0)
  • 2020-11-29 19:21

    I found some pieces of code from Three20 project about this topic, i hope this helps...

    NSMutableArray* TTCreateNonRetainingArray() {
      CFArrayCallBacks callbacks = kCFTypeArrayCallBacks;
      callbacks.retain = TTRetainNoOp;
      callbacks.release = TTReleaseNoOp;
      return (NSMutableArray*)CFArrayCreateMutable(nil, 0, &callbacks);
    }
    
    
    NSMutableDictionary* TTCreateNonRetainingDictionary() {
      CFDictionaryKeyCallBacks keyCallbacks = kCFTypeDictionaryKeyCallBacks;
      CFDictionaryValueCallBacks callbacks = kCFTypeDictionaryValueCallBacks;
      callbacks.retain = TTRetainNoOp;
      callbacks.release = TTReleaseNoOp;
      return (NSMutableDictionary*)CFDictionaryCreateMutable(nil, 0, &keyCallbacks, &callbacks);
    }
    
    0 讨论(0)
提交回复
热议问题