Objective-C ile yazılan programlar, Mach-O ikili dosyalarına derlendiklerinde sınıf bildirimlerini korurlar. Bu sınıf bildirimleri aşağıdaki bilgileri içerir:
Sınıf
Sınıf yöntemleri
Sınıf örnek değişkenleri
Bu bilgilere class-dump kullanarak erişebilirsiniz:
class-dumpKindle.app
Bu isimler, ikili dosyanın tersine çevrilmesini zorlaştırmak için gizlenebilir.
Sınıflar, Metotlar ve Nesneler
Arayüz, Özellikler ve Metotlar
// Declare the interface of the class
@interface MyVehicle : NSObject
// Declare the properties
@property NSString *vehicleType;
@property int numberOfWheels;
// Declare the methods
- (void)startEngine;
- (void)addWheels:(int)value;
@end
Sınıf
@implementation MyVehicle : NSObject
// No need to indicate the properties, only define methods
- (void)startEngine {
NSLog(@"Engine started");
}
- (void)addWheels:(int)value {
self.numberOfWheels += value;
}
@end
Nesne ve Çağrı Yöntemi
Bir sınıfın bir örneğini oluşturmak için alloc yöntemi çağrılır, bu yöntem her bir özelliğe bellek tahsis eder ve bu tahsisleri sıfırlar. Ardından init çağrılır, bu yöntem özellikleri gereken değerlere başlatır.
// Something like this:
MyVehicle *newVehicle = [[MyVehicle alloc] init];
// Which is usually expressed as:
MyVehicle *newVehicle = [MyVehicle new];
// To call a method
// [myClassInstance nameOfTheMethodFirstParam:param1 secondParam:param2]
[newVehicle addWheels:4];
Sınıf Metotları
Sınıf metotları, örnek metotlarla kullanılan tire (-) yerine artı işareti (+) ile tanımlanır. Örneğin, NSString sınıfının stringWithString metodu:
+ (id)stringWithString:(NSString *)aString;
Setter ve Getter
Özellikleri ayarlamak ve almak için, bunu bir nokta gösterimi veya bir metod çağırıyormuş gibi yapabilirsiniz:
// Set
newVehicle.numberOfWheels = 2;
[newVehicle setNumberOfWheels:3];
// Get
NSLog(@"Number of wheels: %i", newVehicle.numberOfWheels);
NSLog(@"Number of wheels: %i", [newVehicle numberOfWheels]);
Örnek Değişkenler
Setter ve getter yöntemlerine alternatif olarak, örnek değişkenlerini kullanabilirsiniz. Bu değişkenler, özelliklerle aynı isme sahip olup "_" ile başlar:
Protokoller, özellikleri olmayan yöntem bildirimlerinin bir kümesidir. Bir protokolü uygulayan bir sınıf, bildirilen yöntemleri uygular.
Yöntemlerin 2 türü vardır: zorunlu ve isteğe bağlı. Varsayılan olarak bir yöntem zorunludur (ancak @required etiketiyle de belirtilebilir). Bir yöntemin isteğe bağlı olduğunu belirtmek için @optional kullanın.
Bu bölümde, Objective-C programlama dilinin temellerini öğreneceğiz. Objective-C, macOS işletim sisteminde yaygın olarak kullanılan bir programlama dilidir. Bu dil, macOS uygulamalarının geliştirilmesinde sıkça kullanılır ve bu nedenle macOS güvenliği ve ayrıcalık yükseltme tekniklerini anlamak için Objective-C hakkında temel bir anlayışa sahip olmak önemlidir.
Objective-C, C programlama diline dayanır ve nesne yönelimli programlama (OOP) özelliklerini içerir. Bu dilde, sınıflar, nesneler ve mesajlar kullanılarak programlar oluşturulur. Sınıflar, nesnelerin şablonlarını tanımlar ve nesneler, sınıfların örnekleridir. Mesajlar ise nesneler arasında iletişimi sağlar.
Objective-C'de, sınıflar ve nesneler arasındaki ilişkiyi belirlemek için "inheritance" (miras alma) ve "polymorphism" (çok biçimlilik) gibi OOP kavramları kullanılır. Miras alma, bir sınıfın başka bir sınıftan özelliklerini ve davranışlarını devralmasını sağlar. Çok biçimlilik ise aynı isimdeki farklı metotların farklı davranışlar sergilemesini sağlar.
Objective-C'de, sınıflar ve nesneler arasındaki iletişim mesajlar aracılığıyla gerçekleştirilir. Bir nesneye mesaj göndermek, o nesnenin belirli bir metotunu çağırmak anlamına gelir. Mesajlar, nesnelerin davranışlarını kontrol etmek için kullanılır.
Objective-C, macOS güvenliği ve ayrıcalık yükseltme tekniklerini anlamak için önemlidir çünkü birçok macOS uygulaması Objective-C dilini kullanır. Bu nedenle, Objective-C'nin temel yapılarını ve çalışma prensiplerini anlamak, macOS üzerindeki güvenlik açıklarını tespit etmek ve ayrıcalık yükseltme saldırıları gerçekleştirmek için önemlidir.
Temel sınıflar değiştirilemez olduğundan, mevcut bir dizeye bir dize eklemek için yeni bir NSString oluşturulması gerekir.
NSString *bookDescription = [NSString stringWithFormat:@"%@ by %@ was published in %@", bookTitle, bookAuthor, bookPublicationYear];
Veya ayrıca bir değiştirilebilir dize sınıfı da kullanabilirsiniz:
NSMutableString *mutableString = [NSMutableString stringWithString:@"The book "];
[mutableString appendString:bookTitle];
[mutableString appendString:@" was written by "];
[mutableString appendString:bookAuthor];
[mutableString appendString:@" and published in "];
[mutableString appendString:bookPublicationYear];
Numara
// character literals.
NSNumber *theLetterZ = @'Z'; // equivalent to [NSNumber numberWithChar:'Z']
// integral literals.
NSNumber *fortyTwo = @42; // equivalent to [NSNumber numberWithInt:42]
NSNumber *fortyTwoUnsigned = @42U; // equivalent to [NSNumber numberWithUnsignedInt:42U]
NSNumber *fortyTwoLong = @42L; // equivalent to [NSNumber numberWithLong:42L]
NSNumber *fortyTwoLongLong = @42LL; // equivalent to [NSNumber numberWithLongLong:42LL]
// floating point literals.
NSNumber *piFloat = @3.141592654F; // equivalent to [NSNumber numberWithFloat:3.141592654F]
NSNumber *piDouble = @3.1415926535; // equivalent to [NSNumber numberWithDouble:3.1415926535]
// BOOL literals.
NSNumber *yesNumber = @YES; // equivalent to [NSNumber numberWithBool:YES]
NSNumber *noNumber = @NO; // equivalent to [NSNumber numberWithBool:NO]
Bloklar, nesne gibi davranan fonksiyonlardır, bu nedenle fonksiyonlara geçirilebilir veya dizilerde veya sözlüklerdesaklanabilir. Ayrıca, değerler verildiğinde bir değeri temsil edebilirler, bu nedenle lambdalara benzerler.
returnType (^blockName)(argumentType1, argumentType2, ...) = ^(argumentType1 param1, argumentType2 param2, ...){
//Perform operations here
};
// For example
int (^suma)(int, int) = ^(int a, int b){
return a+b;
};
NSLog(@"3+4 = %d", suma(3,4));
Ayrıca, işlevlerde kullanılmak üzere bir parametre olarak kullanılmak üzere bir blok türü tanımlamak da mümkündür:
// Define the block type
typedef void (^callbackLogger)(void);
// Create a bloack with the block type
callbackLogger myLogger = ^{
NSLog(@"%@", @"This is my block");
};
// Use it inside a function as a param
void genericLogger(callbackLogger blockParam) {
NSLog(@"%@", @"This is my function");
blockParam();
}
genericLogger(myLogger);
// Call it inline
genericLogger(^{
NSLog(@"%@", @"This is my second block");
});
Dosyalar
// Manager to manage files
NSFileManager *fileManager = [NSFileManager defaultManager];
// Check if file exists:
if ([fileManager fileExistsAtPath:@"/path/to/file.txt" ] == YES) {
NSLog (@"File exists");
}
// copy files
if ([fileManager copyItemAtPath: @"/path/to/file1.txt" toPath: @"/path/to/file2.txt" error:nil] == YES) {
NSLog (@"Copy successful");
}
// Check if the content of 2 files match
if ([fileManager contentsEqualAtPath:@"/path/to/file1.txt" andPath:@"/path/to/file2.txt"] == YES) {
NSLog (@"File contents match");
}
// Delete file
if ([fileManager removeItemAtPath:@"/path/to/file1.txt" error:nil]) {
NSLog(@"Removed successfully");
}
Ayrıca, dosyaları NSString nesneleri yerine NSURL nesneleri kullanarak yönetmek de mümkündür. Yöntem isimleri benzerdir, ancak Path yerine URL kullanılır.
En temel sınıfların çoğu, doğrudan bir dosyaya yazılmalarına izin veren writeToFile:<path> atomically:<YES> encoding:<encoding> error:nil adında bir yönteme sahiptir: