类扩展@interface Class () 功能更强大,可以将变量注入类中.类别@interface Class (Category)不能.
还有什么其他差异,何时应该在类扩展中使用类别?
作为一个相当新的Objective-c程序员(具有4年的Java经验),我似乎很难理解何时使用类扩展.根据我的理解(如果我错了请纠正我),类别和扩展之间的主要区别在于扩展期望您在主实现中实现方法,而对于类别,它可以在另一个实现中.似乎人们主要使用扩展主要用于私有方法.
这是我的第一个问题.使用类扩展来声明私有方法,而不是完全声明它(在两种情况下似乎都在运行中编译)之间的区别是什么?(例1 vs 2)
例1
@interface Class()
-(void) bar;
@end
@implementation Class
-(void) foo {
[self bar];
}
-(void) bar {
NSLog(@"bar");
}
@end
Run Code Online (Sandbox Code Playgroud)
例2
@implementation Class
-(void) foo {
[self bar];
}
-(void) bar {
NSLog(@"bar");
}
@end
Run Code Online (Sandbox Code Playgroud)
第二个问题:在扩展中声明ivars并在实现中直接声明它之间有什么区别?(例3与4)
例3
@interface Class() {
NSArray *mySortedArray;
}
@end
@implementation Class
@end
Run Code Online (Sandbox Code Playgroud)
例4
@implementation Class
NSArray *mySortedArray;
@end
Run Code Online (Sandbox Code Playgroud)
我有关于编码约定的最后一个问题:我应该何时在变量名称前放置下划线(_)?
谢谢
在某些情况下,您可能会覆盖超类的属性.
您声明一个属性与其超类的名称和属性相同.(因为如果您更改属性,则可以获得编译器警告).您可以使用您创建的ivar进行合成.这有什么用?或者它有什么危害呢?
如果超类在类扩展(没有名称的类别)中声明属性,则它可能不在头文件中.如果您不知道头文件中的该属性,则可以使用您想要的属性或类声明相同的名称属性.但是setter/getter方法将覆盖那个"秘密属性"的方法.我认为这只会造成伤害.但既然你不知道头文件,你怎么能避免这个?
您可以将头文件中的属性声明为"readonly",并在类扩展中将其重新声明为"readwrite".我认为这是可以做得好的情况.
我对这些情况的了解是否正确?我不知道第一和第二种情况可以做些什么.但是如果我想避免第一种情况,我可以在声明之前检查子类是否已经具有该属性.但是如果属性不在公共头文件中,就像在第二种情况下那样,我只是不知道该怎么做.
我不明白为什么程序员extension在他们的类实现中使用关键字.您可以阅读其他主题,然后代码在语义上更加分离等等.但是当我使用自己的代码时,我觉得使用它会更清晰// MARK - Something.然后当你在Xcode中使用方法列表(ctrl + 6)时,一切都会在第一眼看到.
在Apple文档中,您可以阅读:
"扩展程序为现有的类,结构或枚举类型添加了新功能."
那么为什么不直接在我自己的类中编写我自己的代码呢?不像我想扩展一些外国类的功能,比如,NSURLSession或者Dictionary,你必须使用扩展.
Mattt Thompson在他的Alamofire图书馆中使用扩展,也许他可以给我一点解释,为什么他选择这种方法.
我有以下类接口:
@interface MyClass : NSObject
@property int publicProperty;
@end
Run Code Online (Sandbox Code Playgroud)
那么实施:
@interface MyClass() // class extension
- (void)privateMethod; // private methods
@end
@implementation MyClass {
int _privateProperty;
}
@property int privateProperty = _privateProperty;
@end
Run Code Online (Sandbox Code Playgroud)
这就是Apple在WWDC中展示的内容,但是有没有理由不将_privateProperty放在类扩展中,如:
@interface MyClass() // class extension
{
int _privateProperty;
}
- (void)privateMethod; // private methods
@end
Run Code Online (Sandbox Code Playgroud)
谢谢!
我正在dlblack.dev 上慢慢建立我的个人网站,并且我正在尝试为它增添一点趣味。例如,从计算机(而不是平板电脑或手机,因为它们没有鼠标指针),如果您将鼠标悬停在任何可点击的项目上,它不会改变您的鼠标指针以表明它是可点击的,并且可点击的对象根本不会改变。我决定遵循这个 FilledStacks 教程,但它没有提到关于解决这个问题的任何内容。
基本上发生的事情是,当我通过教程视频(他在那里编写骨架扩展类)获得大约 2.5 分钟并尝试复制它时,VS Code 将几乎整个类声明(除了名称)红线。我正在写的内容与他在 2:26 屏幕上显示的内容完全相同,这是我的代码:
import 'package:flutter/material.dart';
import 'dart:html' as html;
extension HoverExtension on Widget{
}
Run Code Online (Sandbox Code Playgroud)
当我这样做时,“扩展”、“开”和“小部件”都被红线了。当我将鼠标悬停在“扩展”上时,它会显示以下内容:
Undefined class 'extension'.
Try changing the name to the name of an existing class, or creating a class with the name 'extension'. dartundefined_class
This requires the 'extension-methods' language feature to be enabled.
Try updating your pubspec.yaml to set the minimum SDK constraint to 2.6 or higher, and running 'pub get'. dart(experiment_not_enabled) …Run Code Online (Sandbox Code Playgroud) 将类扩展放在他们自己的.h文件中是否有任何意义,并且#import它们有选择地为类的方法和属性获得不同级别的可见性?如果这是一个坏主意(或不起作用),为什么?
我正在使用第三方库来创建一个使用Swift创建的新应用程序.类/库的作者使用final关键字使其最终成为可能,以优化和防止覆盖其属性和方法.
例:
final public class ExampleClass {
// Properties and Methods here
}
Run Code Online (Sandbox Code Playgroud)
是否有可能扩展类并为其添加一些新属性和方法而不覆盖默认值?
像这样:
extension ExampleClass {
// New Properties and Methods inside
}
Run Code Online (Sandbox Code Playgroud) 我使用的是第三方框架,它提供了一个实例只有属性的类.在我的应用程序中,我想为这个实例添加一个额外的属性.适用于这种情况的适当方法是什么?
a)在我的应用程序中扩展框架的类
b)创建框架类的子类并定义我需要的新属性
提前致谢
以下是处理类扩展的代码段.我要做的是生成一个称为内部ID的随机ID(稍后由程序使用),它以加密形式存储在内存中.代码无法使用gcc和clang编译(我在Windows上通过GNUStep运行Objective C),每个编译器都有不同的错误消息,在代码中作为注释提到.
请注意,我知道这个问题可以通过忽略主@faceface(即#import语句之后的那个)本身的扩展和声明方法和属性来轻松解决.我使用扩展的唯一原因是这个类是由一些其他子类继承的,"internalID"属性必须是不可访问的.
#import <Foundation/Foundation.h>
@interface Foo : NSObject
{
NSString * idStr;
}
- (void)setInternalID;
- (NSString *)fetchExternalID;
@end
// Extension declaration
@interface Foo()
{ // Compilation via gcc throws error at this line stating "Expected identifier or '(' before '{' token"
NSString *internalID; // Compilation via clang throws error at this line stating "instance variables may not be placed in class extension"
}
@end
@implementation Foo
- (void)setInternalID{
internalID = [NSString stringWithFormat:
@"__KEY__INTERNAL__DUMP2872167841398551___8765%d98KLPYFGF(&^$#ESFK___JNHGV",arc4random()%100];
}
- (NSString *)fetchExternalID{
NSString …Run Code Online (Sandbox Code Playgroud) class-extensions ×10
objective-c ×6
swift ×3
properties ×2
alamofire ×1
class ×1
dart ×1
final-class ×1
flutter ×1
flutter-web ×1
gcc ×1
gnustep ×1
ios ×1
llvm-clang ×1
overriding ×1
private ×1
subclass ×1