!!!Obj-c on Mac --- Chapter 5 ~ 7

本文探讨了Objective-C中的组合与继承概念,讲解如何通过包含指向对象的指针来实现组合,并介绍了如何定制NSLog的输出以更好地展示对象状态。此外,还讨论了源文件组织、跨文件依赖及Xcode的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Chapter 5 Composition

In Objective- C, you compose by including pointers to objects as instance variables.

@interface Unicycle : NSObject
{
    Pedal *pedal;
    Tire *tire;
}
@end // Unicycle
Strictly speaking, only objects are said to be composed. More primitive types like int, float, enum, and struct are considered to just be part of the object.

Customizing for NSLog()

@interface Tire : NSObject
@end // Tire
@implementation Tire
- (NSString *) description
{
    return (@"I am a tire. I last a while");
} // description
@end // Tire
When NSLog() processes the %@ specifier, it asks the corresponding object in the parameter list for its description. Speaking technically, NSLog() sends the description message to the object, and the object’s description method builds an NSString and returns it.

By supplying a description method in your class, you can customize how your objects are printed by NSLog().

How to customize descriptionLink

Accessor Methods

Cocoa has conventions for naming accessor methods.

  • Setter methods are named after the attribute they change, preceded by the word “set.” Here are examples of names of setter methods: setEngine:, setStringValue: , setFont:, setFillColor:, and setTextLineHeight:.
  • Getter methods are simply named after the attribute they return. The getters corresponding to the preceding setters would be named engine, stringValue, font, fillColor, and textLineHeight.

The word “get” has a special meaning in Cocoa: in a Cocoa method name, it means the method returns a value via a pointer that you pass in as a parameter. For example, NSData (a Cocoa class for objects that store an arbitrary sequence of bytes) has a method called getBytes:, which takes a parameter that is the address of a memory buffer for holding the bytes.

Composition or Inheritance?

Inheritance sets up an “is a” relationship.

Composition, on the other hand, sets up a “has a” relationship.

Chapter 6 Source File Organization

Split Interface and Implementation

Because of the natural split in the definition of a class into interface and implementation:

  • One part holds the interface components: the @interface directive for the class, any public struct definitions, enum constants, #defines, extern global variables, and so on. Because of Objective- C’s C heritage, this stuff typically goes into a header file, which has the same name as the class with a .h at the end.
  • All the implementation details, such as the @implementation directive for the class, definitions of global variables, private structs, and so on, go into a file with the same name as the class and a .m at the end (sometimes called a dot- m file).

If you use .mm for the file extension, you’re telling the compiler you’ve written your code in Objective- C++, which lets you use C++ and Objective- C together.

When you set up groups, Xcode doesn’t actually move any files or create any directories on your hard drive. The group relationship is just a lovely fantasy maintained by Xcode. If you want, you can set up a group so that it points to a particular place in the file system. Xcode will then put newly created files into that directory for you.

Notice that there are two different ways of doing imports: with quotation marks and with angle brackets. For example, there’s #import <Cocoa/Cocoa.h> and #import "Tire.h". The version with angle brackets is used for importing system header files. The quotes version indicates a header file that’s local to the project. If you see a header file name in angle brackets, it’s read- only for your project, because it’s owned by the system. When a header file name is in quotes, you know that you (or someone else on the project) can make changes to it.

Using Cross- File Dependencies

Importing a header file sets up a strong dependency relationship between the header file and the source file that does the importing. If the header file changes, all the files
dependent on that header file must be recompiled.

Recompiling on a Need-to- Know Basis

when objects are composed (as you saw in the last chapter), the composition uses pointers to objects. This works because all Objective- C objects use dynamically allocated memory. The compiler only needs to know that a particular item is a class. It then knows that the instance variable is the size of a pointer, which is always the same for the
whole program.

Objective-C introduces the @class keyword as a way to tell the compiler, “This thing is a class, and therefore I’m only going to refer to it via a pointer.” This calms the compiler down: it doesn’t need to know more about the class, just that it’s something referred to by a pointer.

@class sets up a forward reference. This is a way to tell the compiler, “Trust me; you’ll learn eventually what this class is, but for now, this is all you need to know.”
@class is also useful if you have a circular dependency. That is, class A uses class B, and class B uses class A. If you try having each class #import the other, you’ll end up with compilation errors. But if you use @class B in A.h and @class A in B.h, the two classes can refer to each other happily.

@class vs. #import    http://stackoverflow.com/questions/322597/class-vs-import         ???

Chapter 7 More About Xcode (Left)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值