Xcode预置Sinppets知多少

前言

NSHipster本周的主题是《Xcode Snippets》,并将他们常用的Snippets放在了GitHub,又引来很多粉丝疯狂的Star,我也过去观望了一下,其实内容不多,而且也没有什么太多的亮点,我觉得只要你平时注意积累和整理自己的Snippets,效果一定比从别人那里Fork来用要好得多。什么?你还不知道Snippets是什么?那你弄清楚了再来看!

其实我平时也不太注意Sinppets的积累和整理,所以决定从现在起开始。在积累自己的Sinppets前,我先大致看了一下Xcode预置的Sinppets,发现不少我曾经千百次敲的代码Sinppets里面都有,所以觉得有比较写成文章记录一下。

Sinppets

现在就按顺序将Xcode预置的Sinppets过一遍。

C Block typedef

Shortcut: typedefBlock

Code:

1
typedef <#return type#>(^<#block name#>)(<#arguments#>);

C Inline Block as Variable

Shortcut: inlineBlock

Code:

1
2
3
<#Return Type#>(^<#Block Name#>)(<#Parameter Types#>) = ^(<#Parameters#>) {
<#Code#>
};

C typedef

Shortcut: typedef

Code:

1
typedef <#existing#> <#new#>;

C++ Class Declaration

Shortcut: classdef

Code:

1
2
3
4
5
6
class <#class name#> {
<#instance variables#>
public:
<#member functions#>
};

C++ Class Template

Shortcut: templateclass

Code:

1
2
3
4
5
6
7
template <<#template parameters#>>
class <#class name#> {
<#instance variables#>
public:
<#member functions#>
};

C++ Function Template

Shortcut: templatefunction

Code:

1
2
3
4
template <<#template parameters#>>
<#return type#> <#function name#>(<#function parameters#>) {
<#statements#>
}

C++ Namespace Definition

Shortcut: namespace

Code:

1
2
3
namespace <#namespace name#> {
<#declarations#>
}

C++ Try / Catch Block

Shortcut: try

Code:

1
2
3
4
5
try {
<#statements#>
} catch (<#catch parameter#>) {
<#statements#>
}

C++ Using Directive

Shortcut: using namespace

Code:

1
using namespace <#namespace name#>

Core Data Basic Fetch

Shortcut:

Code:

1
2
3
4
5
6
7
8
9
10
11
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"<#Entity name#>" inManagedObjectContext:<#context#>];
[fetchRequest setEntity:entity];
NSError *error = nil;
NSArray *fetchedObjects = [<#context#> executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
<#Error handling code#>
}
[fetchRequest release];

比较奇怪的是所有Core Data相关的Snippets都没有提供Shortcut,有知道的朋友麻烦留言告诉我。

Core Data Fetch with a Predicate

Shortcut:

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"<#Entity name#>" inManagedObjectContext:<#context#>];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"<#Predicate string#>", <#Predicate arguments#>];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *fetchedObjects = [<#context#> executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
<#Error handling code#>
}
[fetchRequest release];

Core Data Fetch with Sorting

Shortcut:

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"<#Entity name#>"
inManagedObjectContext:<#context#>];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"<#Sort key#>"
ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *fetchedObjects = [<#context#> executeFetchRequest:fetchRequest error:&error];
if (fetchedObjects == nil) {
// Handle the error
}
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];

Core Data Property Accessors

Shortcut:

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (<#Property type#> *)<#Property name#>
{
[self willAccessValueForKey:@"<#Property name#>"];
<#Property type#> *tmpValue = [self primitiveValueForKey:@"<#Property name#>"];
[self didAccessValueForKey:@"<#Property name#>"];
return tmpValue;
}
- (void)set<#Capitalized property name#>:(<#Property type#> *)value
{
[self willChangeValueForKey:@"<#Property name#>"];
[self setPrimitiveValue:value forKey:@"<#Property name#>"];
[self didChangeValueForKey:@"<#Property name#>"];
}

Core Data Propery Validation

Shortcut:

Code:

1
2
3
4
5
6
- (BOOL)validate<#Capitalized property name#>:(id *)valueRef error:(NSError **)outError
{
BOOL validationResult = YES;
<#Validation code#>
return validationResult;
}

Core Data Scalar Property Accessors

Shortcut:

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- (<#Property type#>)<#Property name#>
{
[self willAccessValueForKey:@"<#Property name#>"];
<#Property type#> *tmpValue = <#Property name#>;
[self didAccessValueForKey:@"<#Property name#>"];
return tmpValue;
}
- (void)set<#Capitalized property name#>:(<#Property type#>)value
{
[self willChangeValueForKey:@"<#Property name#>"];
<#Property name#> = value;
[self didChangeValueForKey:@"<#Property name#>"];
}

Core Data To-Many Relationship Accessors

Shortcut:

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- (void)add<#Capitalized relationship name#>Object:(<#Relationship destination class#> *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"<#Relationship name#>"] addObject:value];
[self didChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueUnionSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)remove<#Capitalized relationship name#>Object:(<#Relationship destination class#> *)value
{
NSSet *changedObjects = [[NSSet alloc] initWithObjects:&value count:1];
[self willChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[[self primitiveValueForKey:@"<#Relationship name#>"] removeObject:value];
[self didChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueMinusSetMutation usingObjects:changedObjects];
[changedObjects release];
}
- (void)add<#Capitalized relationship name#>:(NSSet *)value
{
[self willChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
[[self primitiveValueForKey:@"<#Relationship name#>"] unionSet:value];
[self didChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueUnionSetMutation usingObjects:value];
}
- (void)remove<#Capitalized relationship name#>:(NSSet *)value
{
[self willChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
[[self primitiveValueForKey:@"<#Relationship name#>"] minusSet:value];
[self didChangeValueForKey:@"<#Relationship name#>" withSetMutation:NSKeyValueMinusSetMutation usingObjects:value];
}

Do-While Statement

Shortcut: dowhile

Code:

1
2
3
do {
<#statements#>
} while (<#condition#>);

Enumerate Index Set

Shortcut:

Code:

1
2
3
4
5
6
NSUInteger index = [<#index set#> firstIndex];
while (index != NSNotFound) {
// Do something with index
index = [<#index set#> indexGreaterThanIndex:index];
}

Enumerate Index Set In Reverse

Shortcut:

Code:

1
2
3
4
5
6
NSUInteger index = [<#index set#> lastIndex];
while (index != NSNotFound) {
// Do something with index.
index = [<#index set#> indexLessThanIndex:index];
}

同样,已上两个也没有提供Shortcut。

Enumeration Declaration

Shortcut: enumdef

Code:

1
2
3
4
enum <#enumeration name#> {
<#enumerator1#> = <#value1#>,
<#enumerator2#> = <#value2#>
};

For Statement

Shortcut: for

Code:

1
2
3
for (<#initialization#>; <#condition#>; <#increment#>) {
<#statements#>
}

GCD: Dispatch After

Shortcut: dispatch_after

Code:

1
2
3
4
5
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
<#code to be executed on the main queue after delay#>
});

GCD: Dispatch Once

Shortcut: dispatch_once

Code:

1
2
3
4
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
<#code to be executed once#>
});

If Statement

Shortcut: if

Code:

1
2
3
if (<#condition#>) {
<#statements#>
}

If-Else Statement

Shortcut: ifelse

Code:

1
2
3
4
5
if (<#condition#>) {
<#statements-if-true#>
} else {
<#statements-if-false#>
}

Objective-C Autoreleasing Block

Shortcut: @autoreleasepool

Code:

1
2
3
@autoreleasepool {
<#statements#>
}

Objective-C Catch Block

Shortcut: @catch

Code:

1
2
3
@catch (<#exception#>) {
<#handler#>
}

Objective-C Category

Shortcut: @interface-category

Code:

1
2
3
@interface <#class name#> (<#category name#>)
@end

Objective-C Category Implementation

Shortcut: @implementation-category

Code:

1
2
3
4
5
@implementation <#class#> (<#category name#>)
<#methods#>
@end

Objective-C Class Declaration

Shortcut: @interface

Code:

1
2
3
@interface <#class name#> : <#superclass#>
@end

Objective-C Class Extension

Shortcut: @interface-extension

Code:

1
2
3
@interface <#class name#> ()
@end

Objective-C Class Implementation

Shortcut: @implementation

Code:

1
2
3
4
5
@implementation <#class#>
<#methods#>
@end

Objective-C dealloc Method

Shortcut: dealloc

Code:

1
2
3
4
- (void)dealloc
{
<#deallocations#>
}

Objective-C Fast Enumeration

Shortcut: forin

Code:

1
2
3
for (<#type *object#> in <#collection#>) {
<#statements#>
}

Objective-C Finally Block

Shortcut: @finally

Code:

1
2
3
@finally {
<#handler#>
}

Objective-C init Method

Shortcut: init

Code:

1
2
3
4
5
6
7
8
- (id)init
{
self = [super init];
if (self) {
<#initializations#>
}
return self;
}

Objective-C KVO: Observe Value For Keypath

Shortcut: observeValueForKeyPath

Code:

1
2
3
4
5
6
7
8
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if (context == <#context#>) {
<#code to be executed upon observing keypath#>
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
}
}

Objective-C KVO: Values affecting Key

Shortcut: keyPathsForValuesAffecting

Code:

1
2
3
4
+ (NSSet *)keyPathsForValuesAffecting<#Dependent Key#>
{
return [NSSet setWithObjects:@"<#key1#>", nil];
}

Objective-C Protocol Definition

Shortcut: @protocol

Code:

1
2
3
4
5
@protocol <#protocol name#> <NSObject>
<#methods#>
@end

Objective-C Try / Catch Block

Shortcut: @try

Code:

1
2
3
4
5
6
7
8
9
@try {
<#statements#>
}
@catch (NSException *exception) {
<#handler#>
}
@finally {
<#statements#>
}

###Struct Declaration

Shortcut: structdef

Code:

1
2
3
struct <#struct name#> {
<#instance variables#>
};

Switch Statement

Shortcut: switch

Code:

1
2
3
4
5
6
7
8
switch (<#expression#>) {
case <#constant#>:
<#statements#>
break;
default:
break;
}

Test Method

Shortcut: test

Code:

1
2
3
- (void) test<#Name#> {
<#statements#>
}

###Union Declaration

Shortcut: uniondef

Code:

1
2
3
union <#union name#> {
<#instance variables#>
};

While Statement

Shortcut: while

Code:

1
2
3
while (<#condition#>) {
<#statements#>
}

Objective-C NSCoding initWithCoder Method

Shortcut: initWithCoder

Code:

1
2
3
4
5
6
7
8
- (id)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (self) {
<#initializations#>
}
return self;
}

Objective-C NSView initWithFrame Method

Shortcut: initWithFrame

Code:

1
2
3
4
5
6
7
8
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
<#initializations#>
}
return self;
}

总结

复制粘贴真累,上面贴出来这么长,其实很多根本就不用记,比如:fortypedef等,可以当成Xcode代码补齐功能 , 但有的使用可能需要注意一些条件,如:initdealloc,如果你习惯于一写方法就先写-(id)-(void),那么再打initdealloc就千呼万唤使不出来了,我就躺枪了,你呢? 还有像 observeValueForKeyPathkeyPathsForValuesAffecting 确实不知道,不知道有没有常用KVO的将这两个方法自己又加一遍Snippets?

当然Snippets在添加时可以设置如支持的平台(OS X or iOS),语言环境以及使用的位置(Completion Scopes),用系统预置的Snippets就不用管那么多了,反正苹果会将这些设置为最合理的就是了,我们自己添加Snippets时就得多考虑一下这些设置的参数了。