2012年5月26日 星期六

release and retain for memory

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSNumber          *myInt  = [NSNumber numberWithInteger: 100]; // retainCount =1 in init
NSNumber          *myInt2;
NSMutableArray    *myArr = [NSMutableArray array]; 

// retainCount =1 ,  
NSLog (@ ” myInt retain count = %lx ” ,(unsigned long) [myInt retainCount]);

[myArr addObject: myInt]; // retainCount =2
NSLog (@ ” after adding to array = %lx ” ,(unsigned long) [myInt retainCount]);

myInt2 = myInt; // retainCount =2, 沒有用copy以後可能會有問題
NSLog (@ ” after asssignment to myInt2 = %lx ” ,(unsigned long) [myInt retainCount]);

[myInt retain];// retainCount =3
NSLog (@ ” myInt after retain = %lx ” ,(unsigned long) [myInt retainCount]);
NSLog (@ ” myInt2 after retain = %lx ” ,(unsigned long) [myInt2 retainCount]);

[myInt release]; // retainCount =2 , release後減少1
NSLog (@ ” after release = %lx ” ,(unsigned long) [myInt retainCount]);

[myArr removeObjectAtIndex: 0]; // retainCount =1, 移除後減少了1
NSLog (@ ” after removal from array = %lx ” ,(unsigned long) [myInt retainCount]);

[pool drain];
return 0;
}

myInt retain count = 1
after adding to array = 2
after asssignment to myInt2 = 2
myInt after retain = 3
myInt2 after retain = 3
after release = 2
after removal from array = 1

File Handle Operations

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSFileHandle.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSData.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSFileHandle      *inFile, *outFile;
NSData            *buffer;

// Open the file testfile for reading
inFile = [NSFileHandle fileHandleForReadingAtPath: @ ” testfile ” ];
if (inFile == nil) {
   NSLog (@ ” Open of testfile for reading failed ” );
   return 1;
}

// Create the output file first if necessary
[[NSFileManager defaultManager] createFileAtPath: @ ” testout ” contents: nil attributes: nil];

// Now open outfile for writing
outFile = [NSFileHandle fileHandleForWritingAtPath: @ ” testout ” ];
if (outFile == nil) {
   NSLog (@ ” Open of testout for writing failed ” );
   return 2;
}

// Truncate the output file since it may contain data
[outFile truncateFileAtOffset: 0];

// Read the data from inFile and write it to outFile
buffer = [inFile readDataToEndOfFile]; //把檔案中所有資料讀出
[outFile writeData: buffer]; //寫入輸出檔

// Close the two files
[inFile closeFile];
[outFile closeFile];

// Verify the file ’ s contents
NSLog(@ ” %@ ” , [NSString StringWithContentOfFile: @ ” testout ” ]);
[pool drain];
return 0;
}

Implement a basic copy utility

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

一個copy的執行檔

#import <Foundation/NSString.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSPathUtilities.h>
#import <Foundation/NSProcessInfo.h>

int main (int argc, char *argv[])
{
NSAutoreleasePool  * pool = [[NSAutoreleasePool alloc] init];
NSFileManager      *fm;
NSString           *source, *dest;
BOOL               isDir;
NSProcessInfo      *proc = [NSProcessInfo processInfo];
NSArray            *args = [proc arguments];

fm = [NSFileManager defaultManager];

// Check for two arguments on the command line
if ([args count] != 3) {  //如果不是三個傳入數就不執行
  NSLog (@ ” Usage: %@ src dest ” , [proc processName]);
  return 1;
}

source = [args objectAtIndex: 1]; //第一個傳入變數是原始檔
dest = [args objectAtIndex: 2];

// Make sure the source file can be read
if ([fm isReadableFileAtPath: source] == NO) {
   NSLog (@ ” Can ’ t read %@ ” , source);
   return 2;
}

// See if the destination file is a directory
// if it is, add the source to the end of the destination
[fm fileExistsAtPath: dest isDirectory: &isDir]; //看目的檔是否為目錄
if (isDir == YES) //如果是目錄,就將目錄的後面在加上原始檔名
  dest = [dest stringByAppendingPathComponent:[source lastPathComponent]];

// Remove the destination file if it already exists
[fm removeFileAtPath: dest handler: nil];

// Okay, time to perform the copy
if ([fm copyPath: source toPath: dest handler: nil] == NO) {
   NSLog (@ ” Copy failed! ” );
   return 3;
}
NSLog (@ ” Copy of %@ to %@ succeeded! ” , source, dest);
[pool drain];
return 0;
}

完成後"copy"是執行檔

$ ls –l see what files we have
total 96
-rwxr-xr-x 1 stevekoc staff 19956 Jul 24 14:33 copy
-rw-r--r-- 1 stevekoc staff 1484 Jul 24 14:32 copy.m
-rw-r--r-- 1 stevekoc staff 1403 Jul 24 13:00 file1.m
drwxr-xr-x 2 stevekoc staff   68 Jul 24 14:40 newdir
-rw-r--r-- 1 stevekoc staff 1567 Jul 24 14:12 path1.m
-rw-r--r-- 1 stevekoc staff   84 Jul 24 13:22 testfile
$ copy        try with no args
Usage: copy from-file to-file
$ copy foo copy2
Can ’ t read foo
$ copy copy.m backup.m
Copy of copy.m to backup.m succeeded!
$ diff copy.m backup.m  compare the files
$ copy copy.m newdir    try copy into directory
Copy of copy.m to newdir/copy.m succeeeded!
$ ls –l newdir
total 8
-rw-r--r-- 1 stevekoc staff 1484 Jul 24 14:44 copy.m
$

path operations

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSString.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSPathUtilities.h>

int main (int argc, char *argv[])
{
NSAutoreleasePool  * pool = [[NSAutoreleasePool alloc] init];
NSString           *fName = @ ” path.m ” ;
NSFileManager      *fm;
NSString           *path, *tempdir, *extension, *homedir, *fullpath;
NSString           *upath = @ ” ~stevekochan/progs/../ch16/./path.m ” ;
NSArray            *components;

fm = [NSFileManager defaultManager];

// Get the temporary working directory
tempdir = NSTemporaryDirectory ();
NSLog (@ ” Temporary Directory is %@ ” , tempdir);

// Extract the base directory from current directory
path = [fm currentDirectoryPath];
NSLog (@ ” Base dir is %@ ” , [path lastPathComponent]); //檔案所在的目錄

// Create a full path to the file fName in current directory
fullpath = [path stringByAppendingPathComponent: fName];
NSLog (@ ” fullpath to %@ is %@ ” , fName, fullpath);

// Get the file name extension
extension = [fullpath pathExtension];
NSLog (@ ” extension for %@ is %@ ” , fullpath, extension);

// Get user ’ s home directory
homedir = NSHomeDirectory ();
NSLog (@ ” Your home directory is %@ ” , homedir);

// Divide a path into its components
components = [homedir pathComponents];
for ( path in components)
  NSLog (@ ” %@ ” , path);  //將目錄下的檔案列出

// “ Standardize ” a path 簡化path,
NSLog (@ ” %@ => %@ ” , upath , [upath stringByStandardizingPath] );

[pool drain];
return 0;


Temporary Directory is /var/folders/HT/HTyGLvSNHTuNb6NrMuo7QE+++TI/-Tmp-/
Base dir is examples
fullpath to path.m is /Users/stevekochan/progs/examples/path.m
extension for /Users/stevekochan/progs/examples/path.m is m
Your home directory is /Users/stevekochan
/
Users
stevekochan
~stevekochan/progs/../ch16/./path.m => ~stevekochan/ch16/path.m

Enumerate the contents of a directory

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSString.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSArray.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool     * pool = [[NSAutoreleasePool alloc] init];
NSString              *path;
NSFileManager         *fm;
NSDirectoryEnumerator *dirEnum;
NSArray               *dirArray;

// Need to create an instance of the file manager
fm = [NSFileManager defaultManager]; //所有檔案處理要先定義的動作

// Get current working directory path
path = [fm currentDirectoryPath];

// Enumerate the directory
dirEnum = [fm enumeratorAtPath: path]; //會連次目錄的檔案一併列舉
NSLog (@ ” Contents of %@: ” , path);
while ((path = [dirEnum nextObject]) != nil)
NSLog (@ ” %@ ” , path);

// Another way to enumerate a directory
dirArray = [fm directoryContentsAtPath: [fm currentDirectoryPath]];//只就純檔案  
NSLog (@ ” Contents using directoryContentsAtPath: ” );

for ( path in dirArray )
NSLog (@ ” %@ ” , path);

[pool drain];
return 0;
}

Contents of /Users/stevekochan/mysrc/ch16:
a.out
dir1.m
dir2.m
file1.m
newdir
newdir/file1.m
newdir/output
path1.m
testfile


Contents using directoryContentsAtPath:
a.out
dir1.m
dir2.m
file1.m
newdir
path1.m
testfile

directory operations

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString          *dirName = @ ” testdir ” ;
NSString          *path;
NSFileManager     *fm;

// Need to create an instance of the file manager
fm = [NSFileManager defaultManager];

// Get current directory
path = [fm currentDirectoryPath];
NSLog (@ ” Current directory path is %@ ” , path);

// Create a new directory
if ([fm createDirectoryAtPath: dirName attributes: nil] == NO) {
NSLog (@ ” Couldn ’ t create directory! ” );
return 1;
}

// Rename the new directory
if ([fm movePath: dirName toPath: @ ” newdir ” handler: nil] == NO) {
NSLog (@ ” Directory rename failed! ” );
return 2;
}

// Change directory into the new directory
if ([fm changeCurrentDirectoryPath: @ ” newdir ” ] == NO) {
NSLog (@ ” Change directory failed! ” );
return 3;
}

// Now get and display current working directory
path = [fm currentDirectoryPath];

NSLog (@ ” Current directory path is %@ ” , path);
NSLog (@ ” All operations were successful! ” );
[pool drain];
return 0;
}

Make a copy of a file

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSData.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSFileManager     *fm;
NSData            *fileData;
fm = [NSFileManager defaultManager];

// Read the file newfile2
fileData = [fm contentsAtPath: @ ” newfile2 ” ];
if (fileData == nil) {
   NSLog (@ ” File read failed! ” );
   return 1;
}

// Write the data to newfile3
if ([fm createFileAtPath: @ ” newfile3 ” contents: fileData attributes: nil] == NO) {
   NSLog (@ ” Couldn ’ t create the copy! ” );
   return 2;
}

NSLog (@ ” File copy was successful! ” );
[pool drain];
return 0;

}

Managing Files and Directories: NSFileManager

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSDictionary.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString          *fName = @ ” testfile ” ;
NSFileManager     *fm;
NSDictionary      *attr;

// Need to create an instance of the file manager
fm = [NSFileManager defaultManager];

// Let ’ s make sure our test file exists first
if ([fm fileExistsAtPath: fName] == NO) {
   NSLog (@ ” File doesn ’ t exist! ” );
   return 1;
}

// Now let ’ s make a copy
if ([fm copyPath: fName toPath: @ ” newfile ” handler: nil] == NO) {
   NSLog (@ ” File copy failed! ” );
   return 2;
}
// Let ’ s test to see if the two files are identical
if ([fm contentsEqualAtPath: fName andPath: @ ” newfile ” ] == NO) {
   NSLog (@ ” Files are not equal! ” );
   return 3;
}

// Now let ’ s rename the copy
if ([fm movePath: @ ” newfile ” toPath: @ ” newfile2 ” handler: nil] == NO) {
   NSLog (@ ” File rename failed! ” );
   return 4;
}

// Get the size of newfile2
if ((attr = [fm fileAttributesAtPath: @ ” newfile2 ” traverseLink: NO]) == nil) {
   NSLog (@ ” Couldn ’ t get file attributes! ” );
   return 5;
}
NSLog (@ ” File size is %i bytes ” , [[attr objectForKey: NSFileSize] intValue]);

// And finally, let ’ s delete the original file
if ([fm removeFileAtPath: fName handler: nil] == NO) {
   NSLog (@ ” File removal failed! ” );
   return 6;
}
NSLog (@ ” All operations were successful! ” );

// Display the contents of the newly-created file
NSLog(@ ” %@ ” [NSString stringWithContentsOfFile: @ ” newfile2 ” ]);

[pool drain];
return 0;


File size is 84 bytes
All operations were successful!
This is a test file with some data in it.
Here ’ s another line of data.
And a third.

Set Objects

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSObject.h>
#import <Foundation/NSSet.h>
#import <Foundation/NSValue.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
// Create an integer object
#define INTOBJ(v) [NSNumber numberWithInteger: v]
// Add a print method to NSSet with the Printing category
@interface NSSet (Printing);
-(void) print;
@end
@implementation NSSet (Printing);
-(void) print {
printf ( “ { “ );

for (NSNumber *element in self)
    printf ( “ %li “ , (long) [element integerValue]); // for set1, set2

printf ( “ }\n ” );
}
@end
int main (int argc, char *argv[])
{
NSAutoreleasePool  * pool = [[NSAutoreleasePool alloc] init];
NSMutableSet *set1 = [NSMutableSet setWithObjects:
INTOBJ(1), INTOBJ(3), INTOBJ(5), INTOBJ(10), nil];
NSSet *set2 = [NSSet setWithObjects:
INTOBJ(-5), INTOBJ(100), INTOBJ(3), INTOBJ(5), nil];
NSSet *set3 = [NSSet setWithObjects:
INTOBJ(12), INTOBJ(200), INTOBJ(3), nil];
NSLog (@ ” set1: “ );
[set1 print];
NSLog (@ ” set2: “ );
[set2 print];

// Equality test
if ([set1 isEqualToSet: set2] == NO)
NSLog (@ ” set1 equals set2 ” );
else
NSLog (@ ” set1 is not equal to set2 ” );

// Membership test
if ([set1 containsObject: INTOBJ(10)] == YES)
NSLog (@ ” set1 contains 10 ” );
else
NSLog (@ ” set1 does not contain 10 ” );
if ([set2 containsObject: INTOBJ(10)] == YES)
NSLog (@ ” set2 contains 10 ” );
else
NSLog (@ ” set2 does not contain 10 ” );

// add and remove objects from mutable set set1
[set1 addObject: INTOBJ(4)];
[set1 removeObject: INTOBJ(10)];
NSLog (@ ” set1 after adding 4 and removing 10:  “ );
[set1 print];

// get intersection of two sets
[set1 intersectSet: set2];  //交集
NSLog (@ ” set1 intersect set2:  “ );
[set1 print];

// union of two sets
[set1 unionSet:set3];  //聯集
NSLog (@ ” set1 union set3:  “ );
[set1 print];
[pool drain];
return 0;
}

set1:
{ 3 10 1 5 }
set2:
{ 100 3 -5 5 }
set1 is not equal to set2
set1 contains 10
set2 does not contain 10
set1 after adding 4 and removing 10:
{ 3 1 5 4 }
set1 intersect set2:
{ 3 5 }
set1 union set :
{ 12 3 5 200 }

NSDictionary Objects

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

A dictionary is a collection of data consisting of key-object pairs. Just as you would look up
the definition of a word in a dictionary, you obtain the value (object) from an Objective-
C dictionary by its key.

#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSDictionary.h>
#import <Foundation/NSAutoreleasePool.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool  * pool = [[NSAutoreleasePool alloc] init];
NSMutableDictionary *glossary = [NSMutableDictionary dictionary];
// Store three entries in the glossary
[glossary setObject: @ ” A class defined so other classes can inherit from it ”
forKey: @ ” abstract class ” ];
[glossary setObject: @ ” To implement all the methods defined in a protocol ”
forKey: @ ” adopt ” ];
[glossary setObject: @ ” Storing an object for later use ” forKey: @ ” archiving ” ];
// Retrieve and display them
NSLog (@ ” abstract class: %@ ” , [glossary objectForKey: @ ” abstract class ” ]);
NSLog (@ ” adopt %@ ” , [glossary objectForKey: @ ” adopt ” ]);
NSLog (@ ” archiving %@ ” , [glossary objectForKey: @ ” archiving ” ]);
[pool drain];
return 0;
}

abstract class: A class defined so other classes can inherit from it
adopt: To implement all the methods defined in a protocol
archiving: Storing an object for later use

Synthesize and array

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

AddressCard.h
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
@interface AddressCard: NSObject
{
NSString    *name;
NSString    *email;
}
@property (copy, nonatomic) NSString *name, *email;
-(void) print;
@end

AddressCard.m
#import “ AddressCard.h ”
@implementation AddressCard
@synthesize name, email;
-(void) print
{
NSLog (@ ” ==================================== ” );
NSLog (@ ” |                                  | ” );
NSLog (@ ” |  %-31s | ” , [name UTF8String]);
NSLog (@ ” |  %-31s | ” , [email UTF8String]);
NSLog (@ ” |                                  | ” );
NSLog (@ ” |                                  | ” );
NSLog (@ ” |                                  | ” );
NSLog (@ ” |       O                  O       | ” );
NSLog (@ ” ==================================== ” );
}
-(void) setName: (NSString *) theName andEmail: (NSString *) theEmail
{
self.name = theName;
self.email = theEmail;
}
@end

 Addressbook.h
#import <Foundation/NSArray.h>
#import “ AddressCard.h ”
@interface AddressBook: NSObject
{
NSString        *bookName;
NSMutableArray  *book;
}
-(id) initWithName: (NSString *) name;
-(void) addCard: (AddressCard *) theCard;
-(void) removeCard: (AddressCard *) theCard;
-(AddressCard *) lookup: (NSString *) theName;
-(int)  entries;
-(void) list;
-(void) dealloc;
@end

 Addressbook.m
#import “ AddressBook.h ”
@implementation AddressBook;
// set up the AddressBook ’ s name and an empty book
-(id) initWithName: (NSString *) name
{
   self = [super init];
   if (self) {
      bookName = [ NSString alloc] initWithString: name];
      book = [[NSMutableArray alloc] init];
   }
   return self;
}
-(void) addCard: (AddressCard *) theCard
{
   [book addObject: theCard];
}
-(int) entries
{
   return [book count];
}
-(void) list
{
   NSLog (@ ” ======== Contents of: %@ ========= ” , bookName);
   for ( AddressCard *theCard in book ) // fast enumeration to sequence through each element of  the book array.
       NSLog (@ ” %-20s    %-32s ” , [theCard.name UTF8String],
       [theCard.email UTF8String]);
       NSLog (@ ” ================================================== ” );
}
-(void) dealloc
{
   [bookName release];
   [book release];
   [super dealloc];
}
-(AddressCard *) lookup: (NSString *) theName
{
for ( AddressCard *nextCard in book )
   if ( [[nextCard name] caseInsensitiveCompare: theName] == NSOrderedSame )
      return nextCard;
return nil;
}
-(void) removeCard: (AddressCard *) theCard
{
[book removeObjectIdenticalTo: theCard];
}
-(BOOL) isEqual (AddressCard *) theCard
{
if ([name isEqualToString: theCard.name] == YES &&
   [email isEqualToString: theCard.email] == YES)
   return YES;
else
   return NO;
}
-(void) sort
{
[book sortUsingSelector: @selector(compareNames:)];
}
// Compare the two names from the specified address cards
-(NSComparisonResult) compareNames: (id) element
{
return [name compare: [element name]];
}
@end

 Test Program
#import “ AddressBook.h ”
#import <Foundation/NSAutoreleasePool.h>
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString  *aName = @ ” Julia Kochan ” ;
NSString  *aEmail = @ ” jewls337@axlc.com ” ;
NSString  *bName = @ ” Tony Iannino ” ;
NSString  *bEmail = @ ” tony.iannino@techfitness.com ” ;
NSString  *cName = @ ” Stephen Kochan ” ;
NSString  *cEmail = @ ” steve@kochan-wood.com ” ;
NSString  *dName = @ ” Jamie Baker ” ;
NSString  *dEmail = @ ” jbaker@kochan-wood.com ” ;
AddressCard *card1 = [[AddressCard alloc] init];
AddressCard *card2 = [[AddressCard alloc] init];
AddressCard *card3 = [[AddressCard alloc] init];
AddressCard *card4 = [[AddressCard alloc] init];
AddressBook  *myBook = [AddressBook alloc];
// First set up four address cards
[card1 setName: aName andEmail: aEmail];
[card2 setName: bName andEmail: bEmail];
[card3 setName: cName andEmail: cEmail];
[card4 setName: dName andEmail: dEmail];
// Now initialize the address book
myBook = [myBook initWithName: @ ” Linda ’ s Address Book ” ];
NSLog (@ ” Entries in address book after creation: %i ” ,
[myBook entries]);
// Add some cards to the address book
[myBook addCard: card1];
[myBook addCard: card2];
[myBook addCard: card3];
[myBook addCard: card4];
NSLog (@ ” Entries in address book after adding cards: %i ” ,
[myBook entries]);
// List all the entries in the book now
[myBook list];

// Look up a person by name
NSLog (@ ” Stephen Kochan ” );
myCard = [myBook lookup: @ ” stephen kochan ” ];
if (myCard != nil)
   [myCard print];
else
   NSLog (@ ” Not found! ” );

[myBook sort];
[myBook list];

[myBook removeCard: myCard];
[myBook list];    // verify it ’ s gone

[card1 release];
[card2 release];
[card3 release];
[card4 release];
[myBook release];
[pool drain];
return 0;
}

2012年5月25日 星期五

NSMutableArray

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)


#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSValue.h>
#define MAXPRIME   50

int main (int argc, char *argv[])
{
int     i, p, prevPrime;
BOOL    isPrime;
NSAutoreleasePool   * pool = [[NSAutoreleasePool alloc] init];

// Create an array to store the prime numbers
NSMutableArray  *primes = [NSMutableArray arrayWithCapacity: 20];

// Store the first two primes (2 and 3) into the array
[primes  addObject: [NSNumber numberWithInteger: 2]]  //2是第一個公因數
[primes  addObject: [NSNumber numberWithInteger: 3]];  //3是第二個公因數

// Calculate the remaining primes
for (p = 5; p <= MAXPRIME; p  += 2) {

   // we ’ re testing to see if p is prime
   isPrime = YES;
   i = 1;
   do {
//把公因數依序拿出來
      prevPrime = [[primes objectAtIndex: i] integerValue];  

      if (p % prevPrime == 0) //可以整除的就不是公因數
          isPrime = NO;

      ++i; //找下一個公因數

   } while ( isPrime == YES && p / prevPrime >= prevPrime);

   if (isPrime)  //找到公因數就把它放到primes這個array內
       [primes addObject: [NSNumber numberWithInteger: p]];
 
   //換下一個數字, 直到結束
}

// Display the results
for (i = 0; i < [primes count]; ++i)  //將所有的公因數依序印出
   NSLog (@ ” %li ” , (long) [[primes objectAtIndex: i] integerValue]);

[pool drain];
return 0;
}

在讀取所有的array時,有一個非常方便的方法
id item
for (item in primes)
{

}



參考資料區  http://blog.xuite.net/ray00000test/blog/29036653

NSArray與NSMutableArray與NSMutableDictionary

NSArray:固定長度陣列

使用固定一串資料給NSArray時,必須在陣列最後一個值放入nil,否則會發生錯誤。

範例:
    NSArray *array = [ [ NSArray alloc ] initWithObjects:@"aa",@"bbb",nil];//宣告一陣列放入aa、bb字串
    NSLog(@"array count==%d",array.count);//印出陣列長度
   
    for(int i = 0; i < array.count; i++){//取出陣列裡的字串並印出來
        NSLog(@"i=%@",[array objectAtIndex:i]);
    }
    [array release];//此陣列為暫存,且之後沒用到所以就將陣列從記憶體釋放


=====================================================================================
NSMutableArray:動態陣列

可以不斷放入物件的陣列,陣列長度隨著放入的物件變動
靜態宣告陣列時,一樣必須在陣列最後一個值放入nil,否則會發生錯誤。

範例1    (動態新增):

    NSMutableArray *array = [[NSMutableArray alloc]init];
    [array addObject:@"aa"];
    [array addObject:@"bbb"];
   
    NSLog(@"array count==%d",array.count);
   
    for(int i = 0; i < array.count; i++){
        NSLog(@"i=%@",[array objectAtIndex:i]);
    }
    [array release];


範例2 (靜態放入值+動態新增)

    NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:@"cc",@"ddd",nil];
    [array addObject:@"aa"];
    [array addObject:@"bbb"];
   
    NSLog(@"array count==%d",array.count);
   
    for(int i = 0; i < array.count; i++){
        NSLog(@"i=%@",[array objectAtIndex:i]);
    }
    [array release];



範例3 指定index放入物件,使用insertObject指定位置時,指定的位置必須是 (陣列長度 - 1) 以內的範例值

    NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:@"cc",@"ddd",nil];
    [array addObject:@"aa"];
    [array addObject:@"bbb"];
   
    [array insertObject:@"aaaa" atIndex:4];    //在位置4放入 字串 aaaa




範例4:移除物件

移除指定位置物件
[array removeObjectAtIndex:4];

清除所有物件 
[array removeAllObjects];



範例5:將數值放入陣列

int percentage = 40;

// 產生一個NSNumber物件,可以用signed or unsigned char, short int, int, long int, long long int, float, double or BOOL等基本型態產生物件
NSNumber *percentageObject = [NSNumber numberWithFloat:percentage];

//將NSNumber物件放入array
NSMutableArray *array = [[NSMutableArray alloc]init];
[array addObject:percentageObject];

//取出數值
[percentageObject intValue];


範例6:將指定位置的物件替換掉==>replaceObjectAtIndex:索引值(int) withObject:物件(id) 

    NSMutableArray *array = [[NSMutableArray alloc]initWithObjects:@"cc",@"ddd",nil];
    [array addObject:@"aa"];
    [array addObject:@"bbb"];
   
    for(int i = 0; i < array.count; i++){
        NSLog(@"i=%@",[array objectAtIndex:i]);
    }
   
    [array replaceObjectAtIndex:2 withObject:@"111"];
   
    for(int i = 0; i < array.count; i++){
        NSLog(@"i=%@",[array objectAtIndex:i]);
    }
    [array release];




NSDictionary及NSMutableDictionary(與java的Hashtable相似
============================================================

NSDictionary 及NSMutableDictionary兩種,兩者合稱字典(dictionary),Mutable--善變的--表示可以 變,NSDictionary則像是constant。NSMutableDictionary是NSDictionary的subClass。這就像一 本字典,概念是(key, value),用key來搜尋出所需的value。

NSDictionary:

initWithObjectsAndKeys:

NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys: @"one", [NSNumber numberWithInt: 1], @"two",[NSNumber numberWithInt: 3], nil];

-(id) initWithObjectsAndKeys:(id) firstObject, ....

.....

第一個是firstObject的key,接著是secondObject、key,之後即為object、key的配對,直到出現nil為止。

注意:事實上nil一定出現在object的位置。若key是nil,會產生NSInvalidArgumentException。

NSMutableDictionary:

objectForKey:以下的key是由key = [objectOfNSEnumerator nextObject]; 產生的

[[[objectOfNSMutableDictionary objectForKey:key ] description] cString];

setObject: forKey:[mutable setObject:@"Tom" forKey:@"tom@jones.com"];



範例1: 利用NSEnumerator 取出NSMutableDictionary陣列裡所有的物件,

(1):取得所有value
    NSMutableDictionary *taiStyle = [[NSMutableDictionary alloc]init];
    //所有台型字串
    [taiStyle setObject:[[NSNumber alloc] initWithInt:1] forKey:@"102"];    //
    [taiStyle setObject:[[NSNumber alloc] initWithInt:1] forKey:@"103"];    //

    NSEnumerator *enumerator = [taiStyle objectEnumerator];
    id value;
   
    while ((value = [enumerator nextObject])) {
        NSLog(@"%i",[((NSNumber*)value) intValue]);
    }

(2):取得所有key
    NSMutableDictionary *taiStyle = [[NSMutableDictionary alloc]init];
     //所有台型字串
     [taiStyle setObject:[[NSNumber alloc] initWithInt:1] forKey:@"102"];    //
     [taiStyle setObject:[[NSNumber alloc] initWithInt:1] forKey:@"103"];    //
   
     NSEnumerator *enumerator = [taiStyle keyEnumerator];
    id key;
   
     while ((key = [enumerator nextObject])) {
        NSLog(@"%@",((NSString*)key));
    }

範例2:
    (1)用key取出value物件,使用 valueForKey: key ,若使入的key找不到對應的key,會回傳nil

    [[NSMutableDictionary *taiStyle = [[NSMutableDictionary alloc]init];
    //所有台型字串
    [taiStyle setObject:[[NSNumber alloc] initWithInt:1] forKey:@"102"];    //
    [taiStyle setObject:[[NSNumber alloc] initWithInt:1] forKey:@"103"];    //   

    NSString *key = @"102";
    NSNumber *vlaue = [taiStyle valueForKey:key];
    NSLog(@"%i",[vlaue intValue] );


    (2)指定key移除對應的key與value物件
        [taiStyle removeObjectForKey:@"102"];//移除以@"102"字串當key的物件,key也會被移除

 


Array

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#import <Foundation/NSObject.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h>
#import <Foundation/NSAutoreleasePool.h>
int main (int argc, char *argv[])
{
int    i;
NSAutoreleasePool   * pool = [[NSAutoreleasePool alloc] init];

// Create an array to contain the month names
NSArray  *monthNames = [NSArray  arrayWithObjects:
   @ ” January ” , @ ” February ” , @ ” March ” , @ ” April ” ,
   @ ” May ” , @ ” June ” , @ ” July ” , @ ” August ” , @ ” September ” ,
   @ ” October ” , @ ” November ” , @ ” December ” , nil ];

// Now list all the elements in the array
NSLog (@ ” Month   Name ” );
NSLog (@ ” =====   ==== ” );

for (i = 0; i < 12; ++i)
   NSLog (@ ” %2i     %@ ” , i + 1, [monthNames objectAtIndex: i]);

[pool drain];
return 0;
}

Month   Name
=====   ====
1     January
2     February
3     March
4     April
5     May
6     June
7     July
8     August
9     September
10    October
11    November
12    December

Mutable Strings Operation

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

int main (int argc, char *argv[])
{
NSAutoreleasePool  * pool = [[NSAutoreleasePool alloc] init];
NSString  *str1 = @ ” This is string A ” ;
NSString  *search, *replace;
NSMutableString  *mstr;
NSRange   substr;

// Create immutable string from nonmutable
mstr = [NSMutableString  stringWithString: str1];
NSLog (@ ” %@ ” , mstr);

// Insert characters
[mstr insertString: @ ” mutable ” atIndex: 7];
NSLog (@ ” %@ ” , mstr);

// Effective concatentation if insert at end
[mstr insertString: @ ” and string B ” atIndex: [mstr length]];
NSLog (@ ” %@ ” , mstr);

//  Or can use appendString directly
[mstr appendString: @ ” and string C ” ];
NSLog (@ ” %@ ” , mstr);

// Delete substring based on range
[mstr deleteCharactersInRange: NSMakeRange (16, 13)];
NSLog (@ ” %@ ” , mstr);

// Find range first and then use it for deletion
substr = [mstr  rangeOfString: @ ” string B and  “ ];

if (substr.location != NSNotFound) {
    [mstr deleteCharactersInRange: substr];
    NSLog (@ ” %@ ” , mstr);
}

// Set the mutable string directly
[mstr setString: @ ” This is string A ” ];
NSLog (@ ” %@ ” , mstr);

// Now let ’ s replace a range of chars with another
[mstr replaceCharactersInRange: NSMakeRange(8, 8) withString: @ ” a mutable string ” ];
NSLog (@ ” %@ ” , mstr);

// Search and replace
search = @ ” This is ” ;
replace = @ ” An example of ” ;
substr = [mstr  rangeOfString: search];
if (substr.location != NSNotFound) { // 把" This is "換成"An example of "
   [mstr replaceCharactersInRange: substr withString: replace]; 
   NSLog (@ ” %@ ” , mstr);
}

// Search and replace all occurrences
search = @ ” a ” ;
replace = @ ” X ” ;
substr = [mstr rangeOfString: search];
while (substr.location != NSNotFound) {  //把a換成X
   [mstr replaceCharactersInRange: substr   withString: replace];
   substr = [mstr rangeOfString: search];
}
NSLog (@ ” %@ ” , mstr);

[pool drain];
return 0;
}
This is string A
This is mutable string A
This is mutable string A and string B
This is mutable string A and string B and string C
This is mutable string B and string C
This is mutable string C
This is string A
This is a mutable string
An example of a mutable string
An exXmple of X mutXble string

point and function

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

int arraySum (int array[], int n)
{
int sum = 0, *ptr;
int *arrayEnd = array + n;
for ( ptr = array; ptr < arrayEnd; ++ptr )
sum += *ptr;
return (sum);
}

int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int arraySum (int array[], int n); 
int values[10] = { 3, 7, -9, 3, 6, -1, 7, 9, 1, -5 };
NSLog (@ ” The sum is %i ” , arraySum (values, 10));  // <- 傳入array point
[pool drain];
return 0;
}

point and struct

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)


// normal mode
struct date birthdays[15];  // normal mode

birthdays[1].month = 2;
birthdays[1].day  = 22;
birthdays[1].year = 1996;

// point mode
int main (int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
struct date
{
int month;
int day;
int year;
};
struct date today, *datePtr;  // point mode
datePtr = &today;
datePtr->month = 9;
datePtr->day = 25;
datePtr->year = 2009;
NSLog (@ ” Today ’ s date is %i/%i/%.2i. ” ,
datePtr->month, datePtr->day, datePtr->year % 100);
[pool drain];
return 0;
}

array的一些特殊用法

refer to  Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

int x = 1233;
int a[] = { [9] = x + 1, [2] = 3, [1] = 2, [0] = 1 };

int M[4][5] = {
{ 10, 5, -3, 17, 82 },
{ 9, 0, 0, 8, -7 },
{ 32, 20, 1, 0, 14 },
{ 0, 0, 8, 7, 6 }
};


2012年5月24日 星期四

The ## Operator

refer to Addison Wesley - Programming.in.ObjectiveC.2.0.2nd (2009)

#define printx(n)  printf ( ” %i\n ” , x ## n)
printx (20);
is expanded into the following:
printf ( ” %i\n ” , x20);


寄email給未來的自己

使用
http://www.futureme.org/

寄一封未來的信,問候一下自己
是否還在夢想的道路上。

The @property Statement

refer to http://pernghh.pixnet.net/blog/post/33563421-objective-c-%E5%8F%8A-iphone-sdk-%E5%85%A5%E9%96%80
Objective-C裏的實體變數都會定義它的存取範圍。一般來說外部的物件並不會(該)直接去存取這些變數,而是透過該物件提供的方法來存取,這些方法可以透過在物件的宣告中定義專屬於物件的特性(Property)來讓系統幫我們產生而不必由我們親自動手來撰寫。
雖然在物件中有些變數是允許給外部存取的,但是習慣上我們通常不會直接去存取這些變數,而是透過特性來存取。因為利用特性存取這些變數能夠提供我們許多額外 的好處,包括了簡化物件的記憶體操作、在多執行緒下的變數存取的管理等等。因此,在實務上,即使某個物件將它的某個變數開放出來讓我們使用,我們仍應該先 檢查該變數是否有對應的特性可以使用,如果沒有,而又必須對該變數做操作時才會對變數直接做操作。

特性為類別提供了一個給外面元件存取它內部變數的一個方法。當類別宣告特性之後,系統會自動為特性製作相關的存取方法。這些方法稱為特性的存取方法(accessor method)。存取方法分成下面兩類:
setter
提供設定特性的功能
getter
提供了讀取特性的功能
setter在一般的程式中就是類似 setVariable(),而getter則是 類似getVariable() 的方法。不過這些setter和getter方法並不需要我們自己實作,只要對特性進行適當地設定,系統就會自動幫我們合成這些實作的內容。
特性可以經由設定使它適合在多執行緒的環境使用,因此妥善的特性規劃可以簡化程式的設計,下面是幾種特性的宣告方式
 基本語法
@property (attributes) Type propertyName;
 example
@interface MyClass : NSObject
@property float value;
@end

其中@property float value = 下面兩行的語法

- (float)value;
- (void)setValue:(float)newValue;

 

配合屬性的例子 

@property (nonatomicretain) UIView * testView;
@property (atomic) int fileCount;
@property (nonatomicassign) UIMyDelegete * delegate;
@property (nonatomicassign) UIView * parentView;




refer to http://sevensavants.blogspot.com/2012/03/objective-cdeclared-properties.html


沒用Declared Properties的時候 Accessor需要自己寫

@interface MyClass : NSObject {NSNumber *_myNumber; }
// Accessor - Getter
- (NSNumber *)myNumber;
// Accessor - Setter
- (void)setMyNumber:(NSNumber *)newNumber;
@end


@implementation MyClass
// Accessor - Getter
- (NSNumber *)myNumber {
    return _myNumber;
}
// Accessor - Setter
- (void)setMyNumber:(NSNumber *)newNumber {
   if (newNumber != _myNumber) {
     [_myNumber release];
     _myNumber = [newNumber retain];
   }
}
@end

用Declared Properties之後簡化很多

@interface MyClass : NSObject
@property(retain) myNumber;
@end

@implementation MyClass
@synthesize myNumber
@end

另外properties有很多屬性attributes

Property Declaration Attributes (refer to IOS web)







Accessor Method Names

The default names for the getter and setter methods associated with a property are propertyName and setPropertyName: respectively—for example, given a property “foo”, the accessors would be foo and setFoo:. The following attributes allow you to specify custom names instead. They are both optional and can appear with any other attribute (except for readonly in the case of setter=).
getter=getterName
Specifies the name of the get accessor for the property. The getter must return a type matching the property’s type and take no parameters.
setter=setterName
Specifies the name of the set accessor for the property. The setter method must take a single parameter of a type matching the property’s type and must return void.
If you specify that a property is readonly and also specify a setter with setter=, you get a compiler warning.
Typically you should specify accessor method names that are key-value coding compliant (see Key-Value Coding Programming Guide)—a common reason for using the getter decorator is to adhere to the isPropertyName convention for Boolean values.

Writability

These attributes specify whether or not a property has an associated set accessor. They are mutually exclusive.
readwrite
Indicates that the property should be treated as read/write. This attribute is the default.
Both a getter and setter method are required in the @implementation block. If you use the @synthesize directive in the implementation block, the getter and setter methods are synthesized.
readonly
Indicates that the property is read-only.
If you specify readonly, only a getter method is required in the @implementation block. If you use the @synthesize directive in the implementation block, only the getter method is synthesized. Moreover, if you attempt to assign a value using the dot syntax, you get a compiler error.

Setter Semantics

These attributes specify the semantics of a set accessor. They are mutually exclusive.
strong
Specifies that there is a strong (owning) relationship to the destination object.
weak
Specifies that there is a weak (non-owning) relationship to the destination object.
If the destination object is deallocated, the property value is automatically set to nil.
(Weak properties are not supported on OS X v10.6 and iOS 4; use assign instead.)
copy
Specifies that a copy of the object should be used for assignment.
The previous value is sent a release message.
The copy is made by invoking the copy method. This attribute is valid only for object types, which must implement the NSCopying  protocol.
assign
Specifies that the setter uses simple assignment. This attribute is the default.
You use this attribute for scalar types such as NSInteger and CGRect.
retain
Specifies that retain should be invoked on the object upon assignment.
The previous value is sent a release message.
In OS X v10.6 and later, you can use the __attribute__ keyword to specify that a Core Foundation property should be treated like an Objective-C object for memory management:
@property(retain) __attribute__((NSObject)) CFDictionaryRef myDictionary;

Atomicity

You can use this attribute to specify that accessor methods are not atomic. (There is no keyword to denote atomic.)
nonatomic
Specifies that accessors are nonatomic. By default, accessors are atomic.
Properties are atomic by default so that synthesized accessors provide robust access to properties in a multithreaded environment—that is, the value returned from the getter or set via the setter is always fully retrieved or set regardless of what other threads are executing concurrently.
If you specify strong, copy, or retain and do not specify nonatomic, then in a reference-counted environment, a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value—the implementation will be similar to the following:
[_internal lock]; // lock using an object-level lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;
If you specify nonatomic, a synthesized accessor for an object property simply returns the value directly.

Markup and Deprecation

Properties support the full range of C-style decorators. Properties can be deprecated and support __attribute__ style markup:
@property CGFloat x
AVAILABLE_MAC_OS_X_VERSION_10_1_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_10_4;
@property CGFloat y __attribute__((...));
If you want to specify that a property is an outlet (see outlet in iOS, and outlet in OS X), you use the IBOutlet identifier:
@property (nonatomic, weak) IBOutlet NSButton *myButton;
IBOutlet is not, though, a formal part of the list of attributes. For more about declaring outlet properties, see “Nib Files”.

另外一個例子
@property (nonatomic, copy) NSString *name;
 因為copy這個屬性,得到的 synthesized method that behaves like this:
-(void) setName: (NSString *) theName
{
if (theName != name) {
      [name release]
      name = [theName copy];
   }
}
Use of  nonatomic here tells the system not to protect the property accessors with a
mutex (mutually exclusive) lock

If nonatomic is not specified or  atomic is specified instead (which is the default), then
your instance variable will be protected with a mutex lock.


MyObject *originalObject = [[MyObject alloc] init];
MyObject *duplicatedObject = [originalObject copy];
以上兩行指令已經分配了兩塊 memory。對其中一個 object 所做的改變,不會影響到另外一個,且他們各自的 retain count 為1。
應該說明的是,由於 object 的性質各有不同,如果有需要用到copy指令,你應該為你的object class 加入 -(id)copyWithZone:(NSZone*)zone 函數。有興趣知道更多的話,可以到這裡參考。


參考:http://edwardinaction.blogspot.tw/2012/03/automatic-reference-counting-in.html

手動管理 Reference count
在我們手動管理記憶體 reference count ,程式上會需要 alloc 和 init,這時物件會回傳 retain count,因此在結束後必須要 release 它。




如果不知道呼叫者何時不需要使用,要加上 autorelease。


 
Automatic Reference Counting
有個概念很重要,這不是我們在別的程式語言像是 Java 所提到 Garbage Collection,因為 Garbage Collection 是在 Run-time 期間處理的。這些 Reference Counting 依舊存在,只是在編譯階段幫我們處理掉,讓我們不用再煩惱釋放狀況了。使用了 Automatic Reference Counting 之後,我們則需要寫成這樣。


ARC 的使用方法
  • Alloc, init objects - 當在宣告一個物件時候使用 alloc 和 init,但是千萬不要加上任何的 retain, release 或者 autorelease。當然也不要用任何 Selector 去呼叫 @selector(retain) 或者 @selector(release)。 
  • Dealloc - 就不要在寫 dealloc 了。ARC 會幫我們做到,除非我們想要做些特別處理,但是使用了 dealloc 就不要再呼叫 [super dealloc] 了,這部分也是會幫忙做到。
  • 宣告 Properties - 在還沒有使用 ARC 以前,我們宣告要用到 assign, retain 或者 copy 這些處理記憶體的寫法,這些在 ARC 裡面不會使用了。取而代之的是 weak 和 strong 來告訴編譯器我們在程式上是如何使用的。
  • 使用 Variables - 要使用 strong, weak, unsafe_unretained, autoreleasing。
Strong 與 Weak
  • Strong 的參考上是參考到一個物件一直到當該物件被 deallocted,也就是會幫我們建立出彼此的關聯性,建立彼此的擁有權生命週期。 
  • Weak 的參考上是一直對應到該物件,就算這個物件被 dealloc 了還是存在。所以它不會建立擁有權。
  • _strong 是預設值,所以不打出來就是這樣的方式,建立了物件就會幫忙處理所有的 retained 和 released,自己內部這個物件使用。
  • _weak 代表這個物件可以隨時不見都沒有關係,如果對應到某個物件就算被 dealloc 它就會變成 nil 。
  • unsafe_unretained 這是跟 weak 一樣,但是當物件被 dealloc 不會將指標變成 nil。只是會變成指到無效的物件。
  • _autoreleasing 這會指引到該物件並且建立 autorelease 關係。

基本上,如果沒有特別需求,就使用strong如果一時無法理解也沒關係,如果沒有特別原因,可以先用【基本資料類型不設參數, 類別資料類型設 (nonatomic, strong)】設就可以了,其他的等到學習 delegate,多線程,自訂 setter 等需要參數時,文件中有特別註明是,再來理解就可以了。
 
@property (nonatomic, strong) NSString *testString;
 
 
 
 
在 Project 裡面開啟 ARC
要打開 ARC 只要在 Xcode project’s build setting 找到 reference counting 將它設定為 YES,那麼就會幫我們在編譯階段加上 -fobjc-arc 編譯 flag 來處理。

將既有的 Projects 轉換成為 ARC
打開不是 non-ARC 的 Project 在 Edit -> Refactor -> Convert to Objects-C ARC。會出現一個勾選確認的表單,再點選後程式上會將非 ARC 程式碼轉成 ARC 。如果這過程有些狀況在視情況處理。好了之後可以到 build setting 裡面找 reference counting 是否改為 YES 了。

引用了 Code 不是 ARC 建立出來的
我 們還是可以將 ARC 與 non-ARC 的程式碼並存使用,在 Xcode Project 找到 Target 裡面的 Build Phases tab ,展開 Compile Sources 區域將這些程式碼檔案拍開到 ARC 之外,在後面的 key 地方一一加上 -fno-objc-arc ,目前我還找不到可以一次改多個檔案,所以只好一個一個加。因此當加了這些編譯註記,那麼就會被排外。

最後
如 果新的 Objective-C 學習者,來使用 ARC 會很適合,這可以不用在初期寫程式就傷腦筋 reference count 的管理,而如果像是已經寫 Objective-C 一陣子了如果習慣這樣用法不使用也沒關係,目前為止還是有很多的 libraries 或是 Open Source Projects 還沒轉成 ARC。當然以效能上來說,有些參考數據已經顯示 ARC 可以讓 Project 跑起來更為快速,在 release 或是 autorelease 會用的非常恰當。ARC 的任務是選擇最優化、自動化的方式來幫程式碼加上這些管理。當然最根本程式上不論使用了 ARC 或者 non-ARC,寫 Code 的嚴謹還是最重要的。