Objective-C: ARC
Step to the world!
01
What is it?
Briefly about the main
ARC - Automatic
Reference Counting
• ARC is automatic memory management for Objective-C.
• ARC frees the programmer from the need to explicitly
insert retains and releases.
• ARC is faster then manual memory management.
BUT:
• The programmer should think about memory
management and know how it works.
02
How it works?
The main thing is understanding
ARC is not garbage collector
ARC adds some runtime functions in your code.
For example:
!
This code: Will converted to:
Foo *foo = [[Foo alloc] init]; Foo *foo = [[Foo alloc] init];
[foo something]; [foo something];
return; objc_release(foo);
return;
OR:
Foo *foo = [self foo]; Foo *foo = objc_retainAutoreleasedReturnValue([self foo]);
Bridged casts
A bridged cast is a C-style cast annotated with one
of three keywords:
- __bridge
- __bridge_retained
- __bridge_transfer
__bridge
- (__bridge T) op casts the operand to the destination type T.
If T is a retainable object pointer type, then op must have a
non-retainable pointer type. If T is a non-retainable pointer
type, then op must have a retainable object pointer type.
Otherwise the cast is ill-formed. There is no transfer of
ownership, and ARC inserts no retain operations.
__bridge just casts between pointer-land and Objective-C
object-land. This operand does nothing.
!
Example:
NSString *originalString = (NSString *)self;
CFURLCreateStringByAddingPercentEscapes(NULL,
(__bridge CFStringRef)originalString, NULL, NULL, kCFStringEncodingUTF8);
__bridge_retained
- (__bridge_retained <CFType>) op or alternatively
CFBridgingRetain(op) is used to hand an NSObject over to
CF-land while giving it a +1 retain count. You should handle a
CFTypeRef you create this way the same as you would
handle a result of CFStringCreateCopy(). This could also be
represented by CFRetain((__bridge CFType)op); CFTypeRef
someTypeRef = (__bridge CFType)op;
!
Example:
CFStringRef cf_string = (__bridge_retained
CFStringRef)someNSString;
// some long time later, perhaps in another method etc
CFRelease(cf_string);
__bridge_transfer
-(__bridge_transfer <NSType>) op or alternatively
CFBridgingRelease(op) is used to consume a retain-
count of a CFTypeRef while transferring it over to
ARC. This could also be represented by id someObj
= (__bridge <NSType>) op; CFRelease(op);
!
Example:
!
NSString *string = (__bridge_transfer NSString*) CFStringCreateCopy(NULL,
cf_string);
Pointers
Keywords:
- __autoreleasing
- __strong
- __weak
- __unsafe_unretained
__autoreleasing
__autoreleasing is used to denote arguments that
are passed by reference (id *) and are autoreleased
on return.
!
Example:
NSError *__autoreleasing error;
BOOL ok = [database save:&error];
If you don't use __autoreleasing then compiler creates temp variable:
NSError * error;
NSError *__autoreleasing tmp;
BOOL ok = [database save:&tmp];
__strong
__strong is akin to retain in non-ARC and it’s the default
qualifier of an object variable if no ownership qualifier is
specified.
In the ARC, object lives until there are strong pointers to it.
!
Example:
- (void)nonARC {
id obj = [[MyClass alloc] init];
[obj release];
}
- (void)ARC {
// Obj has a strong reference to MyClass object so it owns
// MyClass object.
id obj = [[MyClass alloc] init];
// When the object variable goes out of scope, the owner
// is discarded and consequently relinquishing ownership of
// MyClass object.
}
__weak
The __weak qualifier is akin to the assign keyword
in non-ARC and is typically used to reference an
object but claims no ownership on that object.
A __weak qualified variable is automatically
assigned to nil (effectively disposing the pointer
variable) after the object it is pointing to is released.
!
Example:
NSDate * __weak originalDate = self.lastModificationDate;
self.lastModificationDate = [NSDate date];
__unsafe_unretained
Qualifiers __unsafe_unretained and __weak are
actually similar in function.
Variables qualified with __unsafe_unretained are
telling the compiler that they do not want to
participate in ARC at all. Hence the programmer is
responsible for allocating/releasing memory and
for handling object lifetimes.
!
Example:
struct MyStruct {
NSString __unsafe_unretained *text;
};
Autorelease
ARC hasn’t NSAutoreleasePool. And if you want use
it, you should use @autoreleasepool.
!
For example:
for (id object in hugeArray) {
@autoreleasepool {
//something with temp variables.
}
}
You still have to call copy for blocks.
And use __weak instead of __block attribute.
!
For example:
SomeBlockType someBlock = ^{
[self someMethod];
};
!
If you try use it under ARC, you’ll get error:
warning: capturing 'self' strongly in this block is likely to lead to a retain cycle
[-Warc-retain-cycles,4]
!
You must use the following code:
__weak SomeObjectClass *weakSelf = self;
SomeBlockType someBlock = ^{
SomeObjectClass *strongSelf = weakSelf;
if (strongSelf) {
[strongSelf someMethod];
}
};
Blocks
03
Practice
Without this, all wasted!
You should create app!
You should create app under ARC. This app should
contains view controller and view.
!
About view controller:
1. Initializing from CFArray(contains CFStrings).
About view:
1. Contains UILabel.
2. When application come from background view changes
label text to random string from array.
!
Other:
Use blocks for notifications.

ARC - Moqod mobile talks meetup

  • 1.
  • 2.
    01 What is it? Brieflyabout the main
  • 3.
    ARC - Automatic ReferenceCounting • ARC is automatic memory management for Objective-C. • ARC frees the programmer from the need to explicitly insert retains and releases. • ARC is faster then manual memory management. BUT: • The programmer should think about memory management and know how it works.
  • 4.
    02 How it works? Themain thing is understanding
  • 5.
    ARC is notgarbage collector ARC adds some runtime functions in your code. For example: ! This code: Will converted to: Foo *foo = [[Foo alloc] init]; Foo *foo = [[Foo alloc] init]; [foo something]; [foo something]; return; objc_release(foo); return; OR: Foo *foo = [self foo]; Foo *foo = objc_retainAutoreleasedReturnValue([self foo]);
  • 6.
    Bridged casts A bridgedcast is a C-style cast annotated with one of three keywords: - __bridge - __bridge_retained - __bridge_transfer
  • 7.
    __bridge - (__bridge T)op casts the operand to the destination type T. If T is a retainable object pointer type, then op must have a non-retainable pointer type. If T is a non-retainable pointer type, then op must have a retainable object pointer type. Otherwise the cast is ill-formed. There is no transfer of ownership, and ARC inserts no retain operations. __bridge just casts between pointer-land and Objective-C object-land. This operand does nothing. ! Example: NSString *originalString = (NSString *)self; CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef)originalString, NULL, NULL, kCFStringEncodingUTF8);
  • 8.
    __bridge_retained - (__bridge_retained <CFType>)op or alternatively CFBridgingRetain(op) is used to hand an NSObject over to CF-land while giving it a +1 retain count. You should handle a CFTypeRef you create this way the same as you would handle a result of CFStringCreateCopy(). This could also be represented by CFRetain((__bridge CFType)op); CFTypeRef someTypeRef = (__bridge CFType)op; ! Example: CFStringRef cf_string = (__bridge_retained CFStringRef)someNSString; // some long time later, perhaps in another method etc CFRelease(cf_string);
  • 9.
    __bridge_transfer -(__bridge_transfer <NSType>) opor alternatively CFBridgingRelease(op) is used to consume a retain- count of a CFTypeRef while transferring it over to ARC. This could also be represented by id someObj = (__bridge <NSType>) op; CFRelease(op); ! Example: ! NSString *string = (__bridge_transfer NSString*) CFStringCreateCopy(NULL, cf_string);
  • 10.
  • 11.
    __autoreleasing __autoreleasing is usedto denote arguments that are passed by reference (id *) and are autoreleased on return. ! Example: NSError *__autoreleasing error; BOOL ok = [database save:&error]; If you don't use __autoreleasing then compiler creates temp variable: NSError * error; NSError *__autoreleasing tmp; BOOL ok = [database save:&tmp];
  • 12.
    __strong __strong is akinto retain in non-ARC and it’s the default qualifier of an object variable if no ownership qualifier is specified. In the ARC, object lives until there are strong pointers to it. ! Example: - (void)nonARC { id obj = [[MyClass alloc] init]; [obj release]; } - (void)ARC { // Obj has a strong reference to MyClass object so it owns // MyClass object. id obj = [[MyClass alloc] init]; // When the object variable goes out of scope, the owner // is discarded and consequently relinquishing ownership of // MyClass object. }
  • 13.
    __weak The __weak qualifieris akin to the assign keyword in non-ARC and is typically used to reference an object but claims no ownership on that object. A __weak qualified variable is automatically assigned to nil (effectively disposing the pointer variable) after the object it is pointing to is released. ! Example: NSDate * __weak originalDate = self.lastModificationDate; self.lastModificationDate = [NSDate date];
  • 14.
    __unsafe_unretained Qualifiers __unsafe_unretained and__weak are actually similar in function. Variables qualified with __unsafe_unretained are telling the compiler that they do not want to participate in ARC at all. Hence the programmer is responsible for allocating/releasing memory and for handling object lifetimes. ! Example: struct MyStruct { NSString __unsafe_unretained *text; };
  • 15.
    Autorelease ARC hasn’t NSAutoreleasePool.And if you want use it, you should use @autoreleasepool. ! For example: for (id object in hugeArray) { @autoreleasepool { //something with temp variables. } }
  • 16.
    You still haveto call copy for blocks. And use __weak instead of __block attribute. ! For example: SomeBlockType someBlock = ^{ [self someMethod]; }; ! If you try use it under ARC, you’ll get error: warning: capturing 'self' strongly in this block is likely to lead to a retain cycle [-Warc-retain-cycles,4] ! You must use the following code: __weak SomeObjectClass *weakSelf = self; SomeBlockType someBlock = ^{ SomeObjectClass *strongSelf = weakSelf; if (strongSelf) { [strongSelf someMethod]; } }; Blocks
  • 17.
  • 18.
    You should createapp! You should create app under ARC. This app should contains view controller and view. ! About view controller: 1. Initializing from CFArray(contains CFStrings). About view: 1. Contains UILabel. 2. When application come from background view changes label text to random string from array. ! Other: Use blocks for notifications.