The following are the notes for learning objective-C 2.0. The original book I purchased is the original English version. Due to my limited level of English, there may be omissions in understanding.
Original book purchase address: Amazon
7. The system frameworks
Item 47: familiarize yourself with the system frameworks
Remember:
(1) You can use multiple system frameworks. The most important two are the foundation and corefoundation, which provide a basic framework library for a variety of applications.
(2) The framework is mainly used to handle public tasks. Such as audio and video control, network and data management.
(3) Remember that the performance of a pure C-written framework is better than that of an objective-C framework. Therefore, as an excellent objective-C developer, you need to understand the core probability of a lot of C.
Item 48: prefer block enumeration to for Loops
Some knowledge points:
(1)
// Reverse fast enumerationNSArray *anArray = /* … */;for (id object in [anArray reverseObjectEnumerator]) { // Do something with `object’}
(2)
// Block enumerationNSArray *anArray = /* … */;[anArray enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop){ // Do something with `object’ if (shouldStop) { *stop = YES; }}];NSDictionary *aDictionary = /* … */;[aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id object, NSUInteger idx, BOOL *stop){ // Do something with `key’ and `object’ if (shouldStop) { *stop = YES; }}];NSSet *aSet = /* … */;[aSet enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL *stop){ // Do something with `object’ if (shouldStop) { *stop = YES; }}];
(3)
// Casting in the block signatureNSDictionary *aDictionary = /* … */;[aDictionary enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *object, NSUInteger idx, BOOL *stop){ // Do something with `key’ and `object’}];
(4)
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);- (void)enumerateKeysAndObjectsWithOptions:(NSEnumerationOptions)opts usingBlock:(void (^)(id key, id obj, BOOL *stop))block NS_AVAILABLE(10_6, 4_0);
Remember:
(1) Enumeration sets can be implemented in four ways. The most basic method is for loop, followed by nsenumerator and quick enumeration. The latest and most efficient method is to use the block enumeration method.
(2) block enumeration can be performed using GCD without adding any additional code. This is hard to provide by Other enumeration technologies.
(3) You can change the parameter type of the Block Method to the object type you have determined.
Item 49: Use toll-free Bridging for collections with custom memory-management Semantics
Some knowledge points:
(1) _ Bridge only performs type conversion, but does not modify the object memory management right;
(2) _ bridge_retained (you can also use cfbridgingretain) to convert the objective-C object to the core foundation object and grant the Object Memory Management Right to the user, cfrelease or related methods will be used to release objects in the future;
(3) _ bridge_transfer (cfbridgingrelease can also be used) converts the core foundation object to the objective-C object, and grants the Object Memory Management Right to arc, cfrelease or related methods are not required to release objects in the future;
Remember:
(1) Free bridging allows you to convert the objective-C object and the pure C object of CF.
(2) Using corefoundation to create objects allows you to customize various callback functions when defining returned content. With this free bridge, you can hand over the CF object to the objective-C object and use the normal memory management semantics.
Item 50: Use nscache instead of nsdictionary for caches
Some knowledge points:
(1)
// Using NSPurgeableData- (void)downloadDataForURL:(NSURL*)url { NSPurgeableData *cachedData = [_cache objectForKey:url]; if (cachedData) { // Stop the data being purged [cacheData beginContentAccess]; [self useData:cachedData]; // Mark that the data may be purged again [cacheData endContentAccess]; } else { // Cache miss EOCNetworkFetcher *fetcher = [[EOCNetworkFetcher alloc] initWithURL:url]; [fetcher startWithCompletionHandler:^(NSData *data){ NSPurgeableData *purgeableData = [NSPurgeableData dataWithData:data]; [_cache setObject:purgeableData forKey:url cost:purgeableData.length]; // Don’t need to beginContentAccess as it begins with access already marked [self useData:data]; // Mark that the data may be purged now [purgeableData endContentAccess]; }]; }}
Remember:
(1) nsdictionary should be used instead of nsdictionary to store the cache. Different from the dictionary, nscache provides the best cleanup behavior, thread security, and does not copy the key.
(2) provide the necessary maximum number and capacity limits for the objects in the cache. But do not use these indicators as hard limits. They are only used to guide the cache release policy.
(3) Use the nspurgeabledata object to store the cache, because it can automatically clean up data and automatically remove it after the cache is released.
(4) correct use of cache can make your program more responsive. The cache is only used for data that is hard to obtain, such as network requests or hard disk reads.
Item 51: Keep initialize and load implementations lean
Some knowledge points:
(1)
// Lean initialize// EOCClass.h#import <Foundation/Foundation.h>@interface EOCClass : NSObject@end// EOCClass.m#import "EOCClass.h"static const int kInterval = 10;static NSMutableArray *kSomeObjects;@implementation EOCClass+ (void)initialize { if (self == [EOCClass class]) { kSomeObjects = [NSMutableArray new]; }}@end
Remember:
(1) If a class implements the load method, the class will traverse the load method during the loading phase. The load method can also be implemented in the category, but the implementation in the class is always prior to the implementation in the category. Unlike other methods, the load method does not overwrite the execution.
(2) The initialize method is executed when a class is used for the first time. This method overwrites the execution, so it is best to check which class is initialized during execution.
(3) Both the load and initialize methods should be implemented in a thin manner, because the response and stop of the application caused by these two methods may lead to internal circular references.
(4) use the initialize method to initialize global variables that cannot be initialized during compilation.
Item 52: Remember that nstimer retains its target
Some knowledge points:
(1)
// Block support for NSTimer#import <Foundation/Foundation.h>@interface NSTimer (EOCBlocksSupport)+ (void)eoc_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats;@end@implementation NSTimer (EOCBlocksSupport)+ (void)eoc_scheduledTimerWithTimeInterval:(NSTimeInterval)interval block:(void(^)())block repeats:(BOOL)repeats{ return [self scheduledTimerWithTimeInterval:interval target:self selector:@selector(eoc_blockInvoke:) userInfo:[block copy] repeats:repeats];}+ (void)eoc_blockInvoke:(NSTimer*)timer { void (^block)() = timer.userInfo; if (block) { block(); }}@end
(2)
// No cycle using weak references- (void)startPolling { __weak EOCClass *weakSelf = self; _pollTimer = [NSTimer eoc_scheduledTimerWithTimeInterval:5.0 block:^{ EOCClass *strongSelf = weakSelf; [strongSelf p_doPoll]; } repeats:YES];}
Remember:
(1) An nstimer object retains the target when triggered until the timer is explicitly set to invalid.
(2) If the time object's target retains the time object, this time object will easily lead to circular reference during execution. This will be directly or not directly triggered by other objects.
(3) The block method can be used to enable the nstimer object to break the extension of this circular reference. To make this block implementation Part Of The nstimer public interface, you can add this block implementation method to nstimer class extension.