This post contains my perusing notes of
the book <Pro Multithreading and Memory Management>, from the components
of ARC to the use of Blocks and Grand Central Dispatch.
Memory Management Actions in Objective-C -
Reference Counting
Activity for Objective-C
Object Objective-C
Method
Make and have responsibility
for/new/duplicate/mutableCopy gathering
Take responsibility for
Surrender it release
Discard it dealloc
+(id)alloc
implementation.m
+ (id) alloc {
return [self allocWithZone:
NSDefaultMallocZone()];
}
+ (id) allocWithZone: (NSZone*)z {
return NSAllocateObject (self, 0, z);
}
struct obj_layout {
NSUInteger held;
};
inline id
NSAllocateObject (Class aClass,
NSUInteger extraBytes, NSZone *zone) {
int estimate =/* required size to store
the question */
id new = NSZoneMalloc(zone, measure);
memset(new, 0, measure);
new = (id)&((struct obj_layout
*)new)[1];
}
The NSAllocateObject work calls
NSZoneMalloc to dispense a memory territory. From that point forward, the
region is loaded with zero and the range pointer is returned.
Objective-C
now overlooks zones, which was utilized to avoid memory discontinuity. The
alloc strategy would now be able to be revised as:
demo.m
struct obj_layout {
NSUInteger held;
};
+ (id) alloc {
int measure = sizeof(struct obj_layout)
+ size_of_the_object;
struct obj_layout *p = (struct
obj_layout *)calloc(1, measure);
return (id)(p + 1);
}
The alloc strategy restores a memory
square loaded with zero containing a struct obj_layout header, which has a
variable "held" to store the quantity of references(reference check).
hold
get reference tally an incentive by
calling retainCount:
demo.m
id obj = [[NSObject alloc] init];
NSLog(@"retainCount=%d", [obj
retainCount]);
/*
* retainCount=1 is shown. */
Execution of hold:
demo.m
- (id) retain{
NSIncrementExtraRefCount(self);
return self;
}
inline void NSIncrementExtraRefCount(id
anObject) {
in the event that (((struct obj_layout
*)anObject)[-1].retained == UINT_MAX - 1)
[NSException raise:
NSInternalInconsistencyException
arrange:
@"NSIncrementExtraRefCount() asked to increase excessively far"];
((struct obj_layout
*)anObject)[-1].retained++; }
at the point when the variable
"held" floods, it's increased.
discharge
demo.m
- (void) discharge {
in the event that (NSDecrementExtraRefCountWasZero(self))
[self dealloc];
}
BOOL
NSDecrementExtraRefCountWasZero(id
anObject) {
in the event that (((struct obj_layout
*)anObject)[-1].retained == 0) {
return YES;
} else {
((struct obj_layout
*)anObject)[-1].retained- - ; restore NO;
}
}
"held" decremented.
dealloc
demo.m
- (void) dealloc {
NSDeallocateObject (self);
}
inline void NSDeallocateObject(id
anObject) {
struct obj_layout *o = &((struct
obj_layout *)anObject)[-1];
free(o);
}
a chunck of memory desposed.
autorelease
like "programmed variable" in
C, which is discarded naturally when the execution leaves the degree.
autorelease implies when execution
leaves a code hinder, the discharge strategy is approached the protest
consequently.
demo.m
- (id) autorelease {
[NSAutoreleasePool addObject:self];
}
ARC(Automatic Reference Counting)
With ARC, "id" and protest
sort factors must have one of the accompanying proprietorship qualifiers:
_strong, _weak, __unsafeunretained,
_autoreleasing
Possession is legitimately overseen by
factor scope, as well as by assignments between factors, which are qualified
with __strong.
Utilize __weak to maintain a strategic
distance from roundabout references:
A __weak possession qualifier gives a
feeble reference. A feeble reference does not have responsibility for protest.
demo.m
id __strong obj0 = [[NSObject alloc]
init];
id __weak obj1 = obj0;
/*
* variable obj1 has a frail reference of
the made question */
_unsafe_unretained: don't utilize it
unless you need to help before iOS5, it may leave a dangling pointer. utilize _weak.
Be that as it may, __weak is solely for
pointers that ought to be focused, not for primitive sorts.
_unsafe_unretained is helpful for
circumstances where you have a question pointer in a circumstance where ARC
doesn't have enough control to securely oversee memory, as within a standard C
struct. That is one reason there's the "no protest pointers in C
struct" restriction, unless you brighten that point with
_unsafe_unretained to tell the compiler you what you're doing. It's likewise used
to break solid reference cycles (a.k.a. hold cycles) with hinders under some
particular conditions.
Be that as it may, for 99.9% of every
day work, feeble works incredible and you can disregard __unsafe_unretained.
Source
Pieces
A Block is created from the Block strict
beginning with "^". Also, the Block is appointed to the variable
"blk". Obviously you can appoint the incentive to different factors
of the Block sort.
Pieces are Anonymous capacities together
with automatic(local)variables.
Assertions (source)
As a nearby factor:
returnType (^blockName)(parameterTypes)
= ^returnType(parameters) {...};
As a property:
@property (nonatomic, duplicate)
returnType (^blockName)(parameterTypes);
As a technique parameter:
(void)someMethodThatTakesABlock:(returnType
(^)(parameterTypes))blockName;
As a contention to a technique call:
[someObject someMethodThatTakesABlock:
^returnType (parameters) {...}];
As a typedef:
typedef returnType
(^TypeName)(parameterTypes);
TypeName blockName =
^returnType(parameters) {...};
block.m
int (^blk1)(int) = blk;
int (^blk2)(int); blk2 = blk1;
/*Functions can take contentions of
Block type.*/
void func(int (^blk)(int)) {
/*Also, capacities can restore a
Block.*/
int (^func()(int)) {
return ^(int count){return tally + 1;};
}
Utilizing typedefs:
block.m
typedef int (^blk_t)(int);
Terrific Central Dispatch
Step by step instructions to utilize:
characterize assignments you need to execute and add them to a suitable
dispatch line.
No comments:
Post a Comment