Rectangle 27 115

Thanks Caleb exactly what was missing from every other page, bar the manual of course :-) thanks for that link.

objective c - How to enable ARC for a single file - Stack Overflow

objective-c automatic-ref-counting
Rectangle 27 45

Simply remove all calls to -release. You're not allowed to call -release under ARC because the compiler will insert all the necessary retain/release calls for you. Read more about ARC here.

The other way is to use the conversion tool, and Xcode can convert your project to ARC (including removing these calls) for you:

However I'd recommend you start using ARC, it will make things a lot easier and actually faster too.

Is there any way to just disable ARC in the LLVM compiler? When I click Convert to Objective-C ARC... it says all targets already use it.

objective c - ARC error when compiling - Stack Overflow

objective-c ios automatic-ref-counting
Rectangle 27 45

Simply remove all calls to -release. You're not allowed to call -release under ARC because the compiler will insert all the necessary retain/release calls for you. Read more about ARC here.

The other way is to use the conversion tool, and Xcode can convert your project to ARC (including removing these calls) for you:

However I'd recommend you start using ARC, it will make things a lot easier and actually faster too.

Is there any way to just disable ARC in the LLVM compiler? When I click Convert to Objective-C ARC... it says all targets already use it.

objective c - ARC error when compiling - Stack Overflow

objective-c ios automatic-ref-counting
Rectangle 27 38

It's mostly right, but assign properties are still treated the same as they ever were, only weak ones are zeroing. Another caveat is that zeroing weak references are only available in Mac OS X 10.7 and iOS 5. While the rest of ARC was backported to 10.6 and iOS 4, weak references cannot be used at all on these OS's.

Thanks for that @cobbal. At least in XCode 4.2 beta, you CANNOT use weak in a property declaration if your deployment target is < iOS 5: you must use assign. Message is error: the current deployment target does not support automated __weak references

Thank you @Yar, I was getting that error and did not know where it came from!

@MarkAdams it does, but as the name implies they are unsafe. When the object a weak references points to is destroyed, the weak reference goes to nil. With unsafe_unretained references, however, the reference points to the same (now deallocated) chunk of memory, and any messages sent to it will likely result in a segfault.

Further note: Mac OS X 10.6 support is limited to 64-bit apps; 32-bit code uses the legacy runtime and cant use ARC at all.

objective c - Zeroing Weak References in ARC - Stack Overflow

objective-c clang automatic-ref-counting
Rectangle 27 38

It's mostly right, but assign properties are still treated the same as they ever were, only weak ones are zeroing. Another caveat is that zeroing weak references are only available in Mac OS X 10.7 and iOS 5. While the rest of ARC was backported to 10.6 and iOS 4, weak references cannot be used at all on these OS's.

Thanks for that @cobbal. At least in XCode 4.2 beta, you CANNOT use weak in a property declaration if your deployment target is < iOS 5: you must use assign. Message is error: the current deployment target does not support automated __weak references

Thank you @Yar, I was getting that error and did not know where it came from!

@MarkAdams it does, but as the name implies they are unsafe. When the object a weak references points to is destroyed, the weak reference goes to nil. With unsafe_unretained references, however, the reference points to the same (now deallocated) chunk of memory, and any messages sent to it will likely result in a segfault.

Further note: Mac OS X 10.6 support is limited to 64-bit apps; 32-bit code uses the legacy runtime and cant use ARC at all.

objective c - Zeroing Weak References in ARC - Stack Overflow

objective-c clang automatic-ref-counting
Rectangle 27 66

Use direct access in partially constructed states, regardless of ARC:

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
        // OR
        reminder = [reminder_ retain];
    }
    return self;
}

This is because self.whatever will trigger other side effects, such as Key-Value Observing (KVO) notifications, or maybe your class implements (explicitly) or a subclass overrides setWhatever: -- and that could expose your partially initialized instance to other APIs (including its own), which rightly assume they are dealing with a fully constructed object.

You could manually verify that a class is capable of operating in a partially initialized state, but that requires a lot maintenance and is (frankly) impractical or impossible when other people want to subclass your class. It requires a lot of time and maintenance, and there isn't substantiative benefit doing so, especially if you try to use the approach as a convention.

So the uniform manner which guarantees correctness is to use direct access in partially constructed states, and avoid using the accessors.

Note: I am using "partially constructed" because initialization is only half of the picture; -dealloc has similar caveats.

Some more detail as to why you should use direct access in partially constructed states (ARC || MRC) can be found here: Initializing a property, dot notation

I'm a bit confused by this when it comes to subclass. If we shouldn't use self.propertyName in init methods, how do you access a parent class's property inside the init method of a subclass ? using _propertyName in subclass says undeclared variable, the only solution is to use self.propertyName. Example: stackoverflow.com/questions/16622776/

@Zhang generally, you should avoid accessing the properties of the base class in initializers. that approach requires your derived class to know about its superclass' implementation, as well as all derived classes which could override the accessor implementations. in objc, you can actually end up calling (the uninitialized) derived class' overridden accessor methods. so you can avoid this headache/risk by: following the advice above, providing more appropriate initializers, using accessors on fully constructed instances, using less complex types (composition), convenience constructors, etc.

@Zhang I think it is safe to call properties from superclass in subclass' init. By the time you reach "body" of subclass' init, superclass' init should have already finished. That means, superclass itself is (or at least should be, if written correctly) already initialized completely. Thus accessing its (= superclass') properties should be safe - even if you override the property in subclass. The problem is when you access the property in init in superclass. In such case, if you override setter in subclass, you may get there with partially initialized object.

@justin ok, so when I subclass UITableViewCell and want to add to add some custom UIView as a subview to its contentView in initialization, what should I do instead of: [self.contentView addSubview:someSubview]; ?

@justin If I construct my UITableViewCell subclass in code (you can not say it is forbidden), then awakeFromNib is not an option. Using lazy initialization in such case is in my opinion simple workaround of a problem. I use lazy initialization only when it is logical (e.g. when non-lazy init is bottleneck which is rather NOT the case here) - not in order to stick to some other (quite not-related) rules... But ok, I think we just have two different approaches and priorities we apply to our code :)

objective c - Should I refer to self.property in the init method with ...

objective-c ios5 initialization automatic-ref-counting reference-counting
Rectangle 27 66

Use direct access in partially constructed states, regardless of ARC:

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
        // OR
        reminder = [reminder_ retain];
    }
    return self;
}

This is because self.whatever will trigger other side effects, such as Key-Value Observing (KVO) notifications, or maybe your class implements (explicitly) or a subclass overrides setWhatever: -- and that could expose your partially initialized instance to other APIs (including its own), which rightly assume they are dealing with a fully constructed object.

You could manually verify that a class is capable of operating in a partially initialized state, but that requires a lot maintenance and is (frankly) impractical or impossible when other people want to subclass your class. It requires a lot of time and maintenance, and there isn't substantiative benefit doing so, especially if you try to use the approach as a convention.

So the uniform manner which guarantees correctness is to use direct access in partially constructed states, and avoid using the accessors.

Note: I am using "partially constructed" because initialization is only half of the picture; -dealloc has similar caveats.

Some more detail as to why you should use direct access in partially constructed states (ARC || MRC) can be found here: Initializing a property, dot notation

I'm a bit confused by this when it comes to subclass. If we shouldn't use self.propertyName in init methods, how do you access a parent class's property inside the init method of a subclass ? using _propertyName in subclass says undeclared variable, the only solution is to use self.propertyName. Example: stackoverflow.com/questions/16622776/

@Zhang generally, you should avoid accessing the properties of the base class in initializers. that approach requires your derived class to know about its superclass' implementation, as well as all derived classes which could override the accessor implementations. in objc, you can actually end up calling (the uninitialized) derived class' overridden accessor methods. so you can avoid this headache/risk by: following the advice above, providing more appropriate initializers, using accessors on fully constructed instances, using less complex types (composition), convenience constructors, etc.

@Zhang I think it is safe to call properties from superclass in subclass' init. By the time you reach "body" of subclass' init, superclass' init should have already finished. That means, superclass itself is (or at least should be, if written correctly) already initialized completely. Thus accessing its (= superclass') properties should be safe - even if you override the property in subclass. The problem is when you access the property in init in superclass. In such case, if you override setter in subclass, you may get there with partially initialized object.

@justin ok, so when I subclass UITableViewCell and want to add to add some custom UIView as a subview to its contentView in initialization, what should I do instead of: [self.contentView addSubview:someSubview]; ?

@justin If I construct my UITableViewCell subclass in code (you can not say it is forbidden), then awakeFromNib is not an option. Using lazy initialization in such case is in my opinion simple workaround of a problem. I use lazy initialization only when it is logical (e.g. when non-lazy init is bottleneck which is rather NOT the case here) - not in order to stick to some other (quite not-related) rules... But ok, I think we just have two different approaches and priorities we apply to our code :)

objective c - Should I refer to self.property in the init method with ...

objective-c ios5 initialization automatic-ref-counting reference-counting
Rectangle 27 66

Use direct access in partially constructed states, regardless of ARC:

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
        // OR
        reminder = [reminder_ retain];
    }
    return self;
}

This is because self.whatever will trigger other side effects, such as Key-Value Observing (KVO) notifications, or maybe your class implements (explicitly) or a subclass overrides setWhatever: -- and that could expose your partially initialized instance to other APIs (including its own), which rightly assume they are dealing with a fully constructed object.

You could manually verify that a class is capable of operating in a partially initialized state, but that requires a lot maintenance and is (frankly) impractical or impossible when other people want to subclass your class. It requires a lot of time and maintenance, and there isn't substantiative benefit doing so, especially if you try to use the approach as a convention.

So the uniform manner which guarantees correctness is to use direct access in partially constructed states, and avoid using the accessors.

Note: I am using "partially constructed" because initialization is only half of the picture; -dealloc has similar caveats.

Some more detail as to why you should use direct access in partially constructed states (ARC || MRC) can be found here: Initializing a property, dot notation

I'm a bit confused by this when it comes to subclass. If we shouldn't use self.propertyName in init methods, how do you access a parent class's property inside the init method of a subclass ? using _propertyName in subclass says undeclared variable, the only solution is to use self.propertyName. Example: stackoverflow.com/questions/16622776/

@Zhang generally, you should avoid accessing the properties of the base class in initializers. that approach requires your derived class to know about its superclass' implementation, as well as all derived classes which could override the accessor implementations. in objc, you can actually end up calling (the uninitialized) derived class' overridden accessor methods. so you can avoid this headache/risk by: following the advice above, providing more appropriate initializers, using accessors on fully constructed instances, using less complex types (composition), convenience constructors, etc.

@Zhang I think it is safe to call properties from superclass in subclass' init. By the time you reach "body" of subclass' init, superclass' init should have already finished. That means, superclass itself is (or at least should be, if written correctly) already initialized completely. Thus accessing its (= superclass') properties should be safe - even if you override the property in subclass. The problem is when you access the property in init in superclass. In such case, if you override setter in subclass, you may get there with partially initialized object.

@justin ok, so when I subclass UITableViewCell and want to add to add some custom UIView as a subview to its contentView in initialization, what should I do instead of: [self.contentView addSubview:someSubview]; ?

@manicaesar it's not very safe; especially as complexity of class hierarchies and classes increase: stackoverflow.com/questions/5932677/ -- true, one can make a provably safe design but who wants to verify that remains safe whenever the implementations are modified? it's complicated/tedious/error prone and doesn't buy you much.

@justin If I construct my UITableViewCell subclass in code (you can not say it is forbidden), then awakeFromNib is not an option. Using lazy initialization in such case is in my opinion simple workaround of a problem. I use lazy initialization only when it is logical (e.g. when non-lazy init is bottleneck which is rather NOT the case here) - not in order to stick to some other (quite not-related) rules... But ok, I think we just have two different approaches and priorities we apply to our code :)

objective c - Should I refer to self.property in the init method with ...

objective-c ios5 initialization automatic-ref-counting reference-counting
Rectangle 27 66

Use direct access in partially constructed states, regardless of ARC:

- (id)initWithReminder:(Reminder*)reminder_ {
    self = [super init];
    if (self) {
        reminder = reminder_;
        // OR
        reminder = [reminder_ retain];
    }
    return self;
}

This is because self.whatever will trigger other side effects, such as Key-Value Observing (KVO) notifications, or maybe your class implements (explicitly) or a subclass overrides setWhatever: -- and that could expose your partially initialized instance to other APIs (including its own), which rightly assume they are dealing with a fully constructed object.

You could manually verify that a class is capable of operating in a partially initialized state, but that requires a lot maintenance and is (frankly) impractical or impossible when other people want to subclass your class. It requires a lot of time and maintenance, and there isn't substantiative benefit doing so, especially if you try to use the approach as a convention.

So the uniform manner which guarantees correctness is to use direct access in partially constructed states, and avoid using the accessors.

Note: I am using "partially constructed" because initialization is only half of the picture; -dealloc has similar caveats.

Some more detail as to why you should use direct access in partially constructed states (ARC || MRC) can be found here: Initializing a property, dot notation

I'm a bit confused by this when it comes to subclass. If we shouldn't use self.propertyName in init methods, how do you access a parent class's property inside the init method of a subclass ? using _propertyName in subclass says undeclared variable, the only solution is to use self.propertyName. Example: stackoverflow.com/questions/16622776/

@Zhang generally, you should avoid accessing the properties of the base class in initializers. that approach requires your derived class to know about its superclass' implementation, as well as all derived classes which could override the accessor implementations. in objc, you can actually end up calling (the uninitialized) derived class' overridden accessor methods. so you can avoid this headache/risk by: following the advice above, providing more appropriate initializers, using accessors on fully constructed instances, using less complex types (composition), convenience constructors, etc.

@Zhang I think it is safe to call properties from superclass in subclass' init. By the time you reach "body" of subclass' init, superclass' init should have already finished. That means, superclass itself is (or at least should be, if written correctly) already initialized completely. Thus accessing its (= superclass') properties should be safe - even if you override the property in subclass. The problem is when you access the property in init in superclass. In such case, if you override setter in subclass, you may get there with partially initialized object.

@justin ok, so when I subclass UITableViewCell and want to add to add some custom UIView as a subview to its contentView in initialization, what should I do instead of: [self.contentView addSubview:someSubview]; ?

@justin If I construct my UITableViewCell subclass in code (you can not say it is forbidden), then awakeFromNib is not an option. Using lazy initialization in such case is in my opinion simple workaround of a problem. I use lazy initialization only when it is logical (e.g. when non-lazy init is bottleneck which is rather NOT the case here) - not in order to stick to some other (quite not-related) rules... But ok, I think we just have two different approaches and priorities we apply to our code :)

objective c - Should I refer to self.property in the init method with ...

objective-c ios5 initialization automatic-ref-counting reference-counting
Rectangle 27 73

The public ARC docs, while not directly clear on this point, seem to suggest that as long as each class is either all ARC or all manually-managed, the classes can be integrated into a single program.

You only can't mix ARC and non-ARC in a single class; the document says that sending retain, release, autorelease, or retainCount messages by any means (including timers and delayed performs, which use @selector) is banned in ARC code. So you can't do non-ARC in an ARC class (because the necessary messages are banned) and you can't do ARC in a non-ARC class (because ARC adds syntax elements that are invalid without ARC).

The same document is a bit clearer on whether you can integrate non-ARC libraries/frameworks into an ARC program: Yes. It doesn't mention whether you can use ARC libraries/frameworks in a program where all your code is non-ARC, but given all of the above, the implication seems to be yes.

Could you share with us what you are doing?

@David H: If you meant to address that to the questioner, you should note that the questioner edited their solution into the question.

ARC compilation cannot be disabled in HEADER files. Clang will NOT compile the interface/header based upon the compilation of it's implementation/method file. Therefore, Header files must be compatible with both ARC and non-ARC in a mixed compilation. I view this as a bug in the compiler.

@carmin: It isn't. The compiler does not look at header files except when you tell it to, which you normally only do by #importing them from module files. The compiler flags setting is for each module file (more precisely, each file in the Compile Sources build phase). The compiler has no way to know whether it should use ARC or not for any other file, except by inheriting the choice it was given for the module file it started with.

objective c - Disable Automatic Reference Counting for Some Files - St...

objective-c ios5 automatic-ref-counting
Rectangle 27 73

The public ARC docs, while not directly clear on this point, seem to suggest that as long as each class is either all ARC or all manually-managed, the classes can be integrated into a single program.

You only can't mix ARC and non-ARC in a single class; the document says that sending retain, release, autorelease, or retainCount messages by any means (including timers and delayed performs, which use @selector) is banned in ARC code. So you can't do non-ARC in an ARC class (because the necessary messages are banned) and you can't do ARC in a non-ARC class (because ARC adds syntax elements that are invalid without ARC).

The same document is a bit clearer on whether you can integrate non-ARC libraries/frameworks into an ARC program: Yes. It doesn't mention whether you can use ARC libraries/frameworks in a program where all your code is non-ARC, but given all of the above, the implication seems to be yes.

Could you share with us what you are doing?

@David H: If you meant to address that to the questioner, you should note that the questioner edited their solution into the question.

ARC compilation cannot be disabled in HEADER files. Clang will NOT compile the interface/header based upon the compilation of it's implementation/method file. Therefore, Header files must be compatible with both ARC and non-ARC in a mixed compilation. I view this as a bug in the compiler.

@carmin: It isn't. The compiler does not look at header files except when you tell it to, which you normally only do by #importing them from module files. The compiler flags setting is for each module file (more precisely, each file in the Compile Sources build phase). The compiler has no way to know whether it should use ARC or not for any other file, except by inheriting the choice it was given for the module file it started with.

objective c - Disable Automatic Reference Counting for Some Files - St...

objective-c ios5 automatic-ref-counting
Rectangle 27 73

The public ARC docs, while not directly clear on this point, seem to suggest that as long as each class is either all ARC or all manually-managed, the classes can be integrated into a single program.

You only can't mix ARC and non-ARC in a single class; the document says that sending retain, release, autorelease, or retainCount messages by any means (including timers and delayed performs, which use @selector) is banned in ARC code. So you can't do non-ARC in an ARC class (because the necessary messages are banned) and you can't do ARC in a non-ARC class (because ARC adds syntax elements that are invalid without ARC).

The same document is a bit clearer on whether you can integrate non-ARC libraries/frameworks into an ARC program: Yes. It doesn't mention whether you can use ARC libraries/frameworks in a program where all your code is non-ARC, but given all of the above, the implication seems to be yes.

Could you share with us what you are doing?

@David H: If you meant to address that to the questioner, you should note that the questioner edited their solution into the question.

ARC compilation cannot be disabled in HEADER files. Clang will NOT compile the interface/header based upon the compilation of it's implementation/method file. Therefore, Header files must be compatible with both ARC and non-ARC in a mixed compilation. I view this as a bug in the compiler.

@carmin: It isn't. The compiler does not look at header files except when you tell it to, which you normally only do by #importing them from module files. The compiler flags setting is for each module file (more precisely, each file in the Compile Sources build phase). The compiler has no way to know whether it should use ARC or not for any other file, except by inheriting the choice it was given for the module file it started with.

objective c - Disable Automatic Reference Counting for Some Files - St...

objective-c ios5 automatic-ref-counting
Rectangle 27 40

You are currently using the ARC to reference count for you. (ARC is "Automatic Reference Counting", a new feature to iOS 5). Therefore you do not need to manually retain or release. You can either remove your retain calls all together or turn off ARC by doing the following:

Click on the name of the project on the navigation view in the left side, go to Targets -> Build Phases and add -fno-objc-arc to the "compiler flags" for any relevant files.

objective c - ARC forbids explicit message send of 'retain' issue - St...

objective-c xcode cocoa memory-management automatic-ref-counting
Rectangle 27 14

Check out WWDC 2012 - Modern Objective-C which outlines new guidelines for Core Foundation objects and ARC. It's about 37:35 into that video. In short, Core Foundation functions with Copy or Create in the name create an object that has transferred ownership to your app, and your app is responsible for releasing it.

Anyway, if ownership has been transferred via a Core Foundation method with Copy or Create in the name, you can either release manually it with CFRelease when you're done with it, or, easier, you can transfer ownership to ARC and let it take care of it. Historically, to transfer ownership to ARC, we used __bridge_transfer, but they now recommend CFBridgingRelease (though the latter is just a macro for the former). And, obviously, if you have some Core Foundation object that you retrieved via some other mechanism other than a function with Copy or Create in the name, you should neither CFRelease it nor transfer ownership to ARC.

By way of illustration, this method accomplishes what you want:

+ (NSString *) fileExtensionForMimeType:(NSString *)type {

    NSString *uti = CFBridgingRelease(UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType,
                                                                            (__bridge CFStringRef)type,
                                                                            NULL));

    return CFBridgingRelease(UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)uti,
                                                             kUTTagClassFilenameExtension));
}

Thanks for the link. Will take a look through that at some point. Very nice and small solution, cheers :)

objective c - ARC and CFRelease? - Stack Overflow

objective-c ios cocoa-touch automatic-ref-counting
Rectangle 27 23

You can only define weak variables in code, ivars or blocks. AFAIK there is no way to dynamically (at runtime) to create a weak variable because ARC takes effect during compile time. When you run the code it already has the retains and releases added for you.

Having said that you can probably abuse blocks to achieve an effect like this.

Have a block that simply returns the reference.

__weak id weakref = strongref;
[weakrefArray addObject:[^{ return weakref; } copy]];

Note that you need to copy the block to get it copied to the heap.

Now you can walk the array anytime you like, dealloc'ed objects in blocks will return nil. You can then remove those.

You cannot have code automatically be executed when the weak ref is zeroed. If this is what you want then you can make use of the function of associated objects. Those get deallocated at the same time as the object they are associated to. So you could have your own sentry tag which informs the weak collection about the objects demise.

You would have one associated object to watch for the dealloc (if the association is the only reference) and the associated object would have a pointer to the collection watching. Then in the sentry dealloc you call the weak collection to inform it that the watched object has gone.

---- DTWeakCollection.h

@interface DTWeakCollection : NSObject

- (void)checkInObject:(id)object;

- (NSSet *)allObjects;

@end

---- DTWeakCollection.m

#import "DTWeakCollection.h"
#import "DTWeakCollectionSentry.h"
#import <objc/runtime.h>

static char DTWeakCollectionSentryKey;

@implementation DTWeakCollection
{
    NSMutableSet *_entries;
}

- (id)init
{
    self = [super init];
    if (self)
    {
        _entries = [NSMutableSet set];
    }
    return self;
}

- (void)checkInObject:(id)object
{
    NSUInteger hash = (NSUInteger)object;

    // make weak reference
    NSNumber *value = [NSNumber numberWithUnsignedInteger:hash];
    [_entries addObject:value];

    // make sentry
    DTWeakCollectionSentry *sentry = [[DTWeakCollectionSentry alloc] initWithWeakCollection:self forObjectWithHash:hash];
    objc_setAssociatedObject(object, &DTWeakCollectionSentryKey, sentry, OBJC_ASSOCIATION_RETAIN);
}

- (void)checkOutObjectWithHash:(NSUInteger)hash
{
    NSNumber *value = [NSNumber numberWithUnsignedInteger:hash];
    [_entries removeObject:value];
}

- (NSSet *)allObjects
{
    NSMutableSet *tmpSet = [NSMutableSet set];

    for (NSNumber *oneHash in _entries)
    {
        // hash is actually a pointer to the object
        id object = (__bridge id)(void *)[oneHash unsignedIntegerValue];
        [tmpSet addObject:object];
    }

    return [tmpSet copy];
}

@end

---- DTWeakCollectionSentry.h

#import <Foundation/Foundation.h>
@class DTWeakCollection;

@interface DTWeakCollectionSentry : NSObject

- (id)initWithWeakCollection:(DTWeakCollection *)weakCollection forObjectWithHash:(NSUInteger)hash;

@end

--- DTWeakCollectionSentry.m


#import "DTWeakCollectionSentry.h"
#import "DTWeakCollection.h"

@interface DTWeakCollection (private)

- (void)checkOutObjectWithHash:(NSUInteger)hash;

@end

@implementation DTWeakCollectionSentry
{
    __weak DTWeakCollection *_weakCollection;
    NSUInteger _hash;
}

- (id)initWithWeakCollection:(DTWeakCollection *)weakCollection forObjectWithHash:(NSUInteger)hash
{
    self = [super init];

    if (self)
    {
        _weakCollection = weakCollection;
        _hash = hash;
    }

    return self;
}

- (void)dealloc
{
    [_weakCollection checkOutObjectWithHash:_hash];
}

@end

This would be used like this:

NSString *string = @"bla";

@autoreleasepool {
_weakCollection = [[DTWeakCollection alloc] init];
    [_weakCollection checkInObject:string];

__object = [NSNumber numberWithInteger:1123333];

[_weakCollection checkInObject:__object];
}

if you output allObjects inside the autorelease pool block then you have two objects in there. Outside you only have the string.

I found that in the dealloc of the entry the object reference is already nil, so you cannot use __weak. Instead I am using the memory address of the object as hash. While these are still in _entries you can treat them as actual object and the allObjects returns an autoreleased array of strong references.

Note: this is not thread safe. Do deal with dealloc's on non-main queues/threads you would need to be careful to synchronize accessing and mutating the internal _entries set.

Note 2: This currently only works with objects checking into a single weak collection since a second check in would overwrite the associated sentry. If you needed this with multiple weak collections then the sentry instead should have an array of those collections.

Note 3: I changed the sentry's reference to the collection to weak as well to avoid a retain cycle.

Note 4: Here are a typedef and helper functions which handle the block syntax for you:

typedef id (^WeakReference)(void);

WeakReference MakeWeakReference (id object) {
    __weak id weakref = object;
    return [^{ return weakref; } copy];
}

id WeakReferenceNonretainedObjectValue (WeakReference ref) {
    if (ref == nil)
        return nil;
    else
        return ref ();
}

Re note 2: you only ever set an associated object, the key is never used again, so could you not use sentry itself as the key? Would that not cope with an object being entered into a collection twice or into different collections?

Thanks for this answer! Using a block as a wrapper is working well. I wrote a typedef and a couple helper functions to make it a little easier to use. I can paste those into the end of your answer if you'd like.

@CRD No, the key needs to be in static memory.

@Cocoanetics - The key doesn't need to be static, it is just that a static is usually used. The docs state "The key is a void pointer. The key for each association must be unique. A typical pattern is to use a static variable." This makes sense, it is probably just using a unique 64-bit value as the key. I think in your case as you never need to retrieve the association you don't need to actually know the key...

@Cocoanetics, the code for the self-updating collection is more than I need for this particular application. I was glad to try out the block-based solution which does work, but the wrapper object is easier for me to understand.

objective c - Collections of zeroing weak references under ARC - Stack...

objective-c cocoa-touch cocoa automatic-ref-counting weak-references
Rectangle 27 16

I'm going to assume your'e using ARC here. Prior to ARC, your first example would work just fine. With ARC the semantics of __block have changed. __block declarations are now strongly captured, rather than weakly. Replace __block with __weak in your first sample and all should work as expected.

As for what the second example works, you are creating a strong reference to the delegate, but your that doesn't have a reference back to your object. Thus no cycle and everyone is happy.

__weak

I'm targeting iOS 4.3, so I've had to use __unsafe_unretained instead, but it works, thanks!

objective c - __block self reference cycle in ivar block in ARC - Stac...

objective-c memory-management automatic-ref-counting objective-c-blocks grand-central-dispatch
Rectangle 27 16

Clang's technical specification of ARC goes into much more detail about how the qualifiers work.

But, to answer your question: assign and __unsafe_unretained are not the same thing. assign is a property attribute that tells the compiler how to synthesise the property's setter implementation, while __unsafe_unretained is an ownership qualifier that tells ARC how to insert retain/release calls. But they are related: when declaring a property, assign implies __unsafe_unretained ownership.

Prior to ARC, assign was the default property ownership qualifier; but with ARC enabled, the default for retainable object pointer types is strong. (For scalars and other pointer types, assign is still the default.)

Yes, for iOS 4.3, you should use unsafe_unretained or assign since weak isn't available. Just be conscious that any pointer with these lifetime qualifiers will not be automatically zeroed after a deallocation (thus there is the possibility they may become a dangling pointer). Also, and I believe this may have changed since the original answer was written, but the default qualifier for an object property in ARC is strong not assign

I think this response misses the original poster's question, which was about the difference between the assign and unsafe_unretained (no double-underscore prefix) property attributes. According to section 4.1 of the document linked to above, these two attributes both map to __unsafe_unretained (with the underscores) ownership, and do actually appear to be equivalent. I think the only difference is that, under ARC, one should use assign for non-pointers, and unsafe_unretained for pointer types.

You don't really see unsafe_unretained in property declarations. It's either weak/strong or assign/strong for non-ARC. The only time I have ever used __unsafe_unretained (with 2 underscores) is to keep object pointers in a struct: Struct s { __unsafe_unretained id obj ; } ;

The purpose of unsafe_unretained as a property attribute is to provide a scarier looking synonym for assign. The logic is that if it is unsafe, it should look unsafe.

I like "scarier looking synonym" --- very apt description. :-) The point, of course, is call attention to the extra care required around the use of the property.

objective c - using ARC, lifetime qualifier assign and unsafe_unretain...

objective-c ios automatic-ref-counting
Rectangle 27 16

Clang's technical specification of ARC goes into much more detail about how the qualifiers work.

But, to answer your question: assign and __unsafe_unretained are not the same thing. assign is a property attribute that tells the compiler how to synthesise the property's setter implementation, while __unsafe_unretained is an ownership qualifier that tells ARC how to insert retain/release calls. But they are related: when declaring a property, assign implies __unsafe_unretained ownership.

Prior to ARC, assign was the default property ownership qualifier; but with ARC enabled, the default for retainable object pointer types is strong. (For scalars and other pointer types, assign is still the default.)

Yes, for iOS 4.3, you should use unsafe_unretained or assign since weak isn't available. Just be conscious that any pointer with these lifetime qualifiers will not be automatically zeroed after a deallocation (thus there is the possibility they may become a dangling pointer). Also, and I believe this may have changed since the original answer was written, but the default qualifier for an object property in ARC is strong not assign

I think this response misses the original poster's question, which was about the difference between the assign and unsafe_unretained (no double-underscore prefix) property attributes. According to section 4.1 of the document linked to above, these two attributes both map to __unsafe_unretained (with the underscores) ownership, and do actually appear to be equivalent. I think the only difference is that, under ARC, one should use assign for non-pointers, and unsafe_unretained for pointer types.

You don't really see unsafe_unretained in property declarations. It's either weak/strong or assign/strong for non-ARC. The only time I have ever used __unsafe_unretained (with 2 underscores) is to keep object pointers in a struct: Struct s { __unsafe_unretained id obj ; } ;

The purpose of unsafe_unretained as a property attribute is to provide a scarier looking synonym for assign. The logic is that if it is unsafe, it should look unsafe.

I like "scarier looking synonym" --- very apt description. :-) The point, of course, is call attention to the extra care required around the use of the property.

objective c - using ARC, lifetime qualifier assign and unsafe_unretain...

objective-c ios automatic-ref-counting
Rectangle 27 54

You can use one of the lifetime qualifiers described in the Transitioning to ARC Release Notes

For NSError ** you'd use __autoreleasing so the example provided by Nikolai would then look like this

@interface Foo : NSObject
{
    NSError * __autoreleasing *error;
}

The syntax is a little weird and you should follow Nikolais advice, but if you're sure NSError ** is what you want this should work.

NSError * __autoreleasing *_error;

This is the correct answer. It is not wrong to do this as the answer by @NikolaiRuhe states.

Thanks for this answer! I'd like to add that I've also used other lifetime qualifiers with this same syntax, like NSArray * __strong *array, etc.

objective c - Automatic Reference Counting: Pointer to non-const type ...

objective-c ios ios5 automatic-ref-counting
Rectangle 27 4

The case to worry about is something like addObserverForName:object:queue:usingBlock:. The docs say, "The block is copied by the notification center." Under ARC, that word "copy" is a red flag; now you need to take steps so that you (the caller) will not leak.

EDIT: Also, sometimes ARC itself will alert you. The completion block of -[UIPageViewController setViewControllers:direction:animated:completion:] is a case in point. I would never have suspected that using self here might cause a retain cycle, but ARC warned that it would, so I did the weak-strong dance just in case.

That's probably ARC being cautious: You're passing a block that retains self to a method beginning with "set". -addObserverForName:object:queue:usingBlock:, OTOH, is an invitation for subtle bugs: You also to hold on to the return value so you can pass it to -removeObserver: later.

objective c - ARC, ivars in Blocks and Reference Cycles via Captured S...

objective-c ios ios5 objective-c-blocks automatic-ref-counting